Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Py: Add support for importing models from Hugging Face Hub #260

Merged
merged 7 commits into from
Jan 17, 2024
Merged

Py: Add support for importing models from Hugging Face Hub #260

merged 7 commits into from
Jan 17, 2024

Conversation

isinyaaa
Copy link
Contributor

@isinyaaa isinyaaa commented Jan 3, 2024

Related: #133

Description

Fixes docstrings and some type errors, also simplifies type checking in ProtoBase.unmap and MLMDStore.get_type_id.

As laid out in opendatahub-io/model-registry#133 (comment), the API provides
utility calls to fetch metadata from a given Hub repo automatically.

The following metadata is fetched:

Additional data regarding the origin of the model is also stored in the model version created by the import.

TODO:

  • Skip feature tests if huggingface-hub lib isn't installed.
  • Import hf model author
  • Get metadata from user-provided git ref

How Has This Been Tested?

Merge criteria:

  • The commits and have meaningful messages; the author will squash them after approval or will ask to merge with squash.
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has manually tested the changes and verified that the changes work

@isinyaaa isinyaaa self-assigned this Jan 3, 2024
tarilabs
tarilabs previously approved these changes Jan 4, 2024
Copy link
Member

@tarilabs tarilabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I'm good with merging this early and adapting for storageUri if needed (more below) in subsequent PRs too.

Comment on lines 170 to 172
urljoin(
"https://huggingface.co", f"{repo}/resolve/{git_ref or 'main'}/{path}"
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lampajr as we're storing the "raw binary URL" when import from HF, I believe we will need to make sure in MC reconciliation we're not using Secret/S3 but the storageURI similar to:

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  annotations:
    openshift.io/display-name: example
    serving.kserve.io/deploymentMode: ModelMesh
  name: example
  namespace: ds-mre2e
  labels:
    opendatahub.io/dashboard: 'true'
spec:
  predictor:
    model:
      modelFormat:
        name: onnx
        version: '1'
      name: ''
      resources: {}
      runtime: mmserver1
      storageUri: https://github.com/tarilabs/demo20231212/blob/main/v1.nb20231206162408/mnist.onnx?raw=true

(this example demonstrates using binary from GitHub, but analogously using the raw binary URI from HF as highlighted.

Wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 if we have different ways to create IS based on the nature of the model (either "internal" using s3 and the data connection or "external" using the storageUri).

Instead, if we decide to go with https://github.com/opendatahub-io/model-registry/issues/254 we will have a standardized way to create IS using storageUri only, this way we don't have to create different IS based on the model nature but just use the single model-registry specific way.

clients/python/tests/test_client.py Show resolved Hide resolved
@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 4, 2024

I'd like your opinion on the metadata imports, specifically in regards to lists. We have two options right now:

  1. Support that in a non-standard way (e.g. what was proposed on hf POC).
  2. Discard all list metadata except for tags which we know how to deal with.

@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 4, 2024

Also, as discussed previously, regarding the upload limits on deployed clusters, do you think it'd be better to crop large README.md files to some character limit or simply don't use it?

@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 4, 2024

Changes in v2:

  • huggingface-hub is now properly marked as an optional dependency
  • Related tests are skipped if the dependency is not available

Edit: updated the README.md to add install instructions for the extra group.

@codecov-commenter
Copy link

codecov-commenter commented Jan 4, 2024

Codecov Report

Attention: 21 lines in your changes are missing coverage. Please review.

Comparison is base (97a976b) 0.00% compared to head (3acdb01) 74.16%.

Files Patch % Lines
clients/python/src/model_registry/_client.py 55.00% 14 Missing and 4 partials ⚠️
clients/python/src/model_registry/types/base.py 66.66% 1 Missing and 1 partial ⚠️
clients/python/src/model_registry/store/wrapper.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           main     #260       +/-   ##
=========================================
+ Coverage      0   74.16%   +74.16%     
=========================================
  Files         0       17       +17     
  Lines         0     2295     +2295     
  Branches      0       73       +73     
=========================================
+ Hits          0     1702     +1702     
- Misses        0      426      +426     
- Partials      0      167      +167     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 4, 2024

Should we test extras on the default CI jobs or add new ones? @tonyxrmdavidson @rkubis

@tarilabs
Copy link
Member

tarilabs commented Jan 4, 2024

I'd like your opinion on the metadata imports, specifically in regards to lists. We have two options right now:

  1. Support that in a non-standard way (e.g. what was proposed on hf POC).
  2. Discard all list metadata except for tags which we know how to deal with.

I believe we need to decide about this more in general since we'll be asked from UI team how to store lists as custom_property, and I recall there is some limitations in the tradeoff between what allowed by MLMD and what possible as k8s resources. To be determined.

Also, as discussed previously, regarding the upload limits on deployed clusters, do you think it'd be better to crop large README.md files to some character limit or simply don't use it?

Did we confirm where the gRPC limit is coming from? 🤔 is this an hard-coded limit in MLMD server?

Copy link
Contributor

@lampajr lampajr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me, left a change request as I think it could break the functionality

clients/python/src/model_registry/types/contexts.py Outdated Show resolved Hide resolved
@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 4, 2024

I'd like your opinion on the metadata imports, specifically in regards to lists. We have two options right now:

  1. Support that in a non-standard way (e.g. what was proposed on hf POC).
  2. Discard all list metadata except for tags which we know how to deal with.

I believe we need to decide about this more in general since we'll be asked from UI team how to store lists as custom_property, and I recall there is some limitations in the tradeoff between what allowed by MLMD and what possible as k8s resources. To be determined.

I'll assume it's safer to discard those for now then. As for the tags, see the discussion above.

Also, as discussed previously, regarding the upload limits on deployed clusters, do you think it'd be better to crop large README.md files to some character limit or simply don't use it?

Did we confirm where the gRPC limit is coming from? 🤔 is this an hard-coded limit in MLMD server?

Unfortunately, just looking at the source code, it's only apparent that it's an absl warning from the server, but I wasn't able to find where it's being thrown.

For future reference, the error we get for e.g. aident-ai/bge-base-en-onnx is:

ResourceExhaustedError: received metadata size exceeds hard limit (value length 29943 vs. 16384)

From the gRPC status code reference this means that "Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space." which isn't too clear still.

I'm investigating whether it's possible to override some connection parameter (as per this SO answer) to make that work, but I'm confused as to why local tests don't raise this.

@isinyaaa isinyaaa requested review from tarilabs and lampajr January 5, 2024 18:55
@tarilabs
Copy link
Member

tarilabs commented Jan 8, 2024

I'm investigating whether it's possible to override some connection parameter (as per this SO answer) to make that work, but I'm confused as to why local tests don't raise this.

So far, I was only able to get a different error:

_InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
	status = StatusCode.INTERNAL
	details = "PostgreSQL metadata source error: ERROR:  index row requires 20888 bytes, maximum size is 8191
"
	debug_error_string = "UNKNOWN:Error received from peer  {created_time:"2024-01-08T10:07:45.075406312+00:00", grpc_status:13, grpc_message:"PostgreSQL metadata source error: ERROR:  index row requires 20888 bytes, maximum size is 8191\n"}"
>

edit: can be replicated beyond MR python client using REST with:

curl -X 'POST' \
  'https://mr-secure-ds-mre2e.apps.rosa.mmortari-rosa-h.w0x4.p3.openshiftapps.com/api/model_registry/v1alpha1/registered_models' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "---\r\ntags:\r\n- sentence-transformers\r\n- feature-extraction\r\n- sentence-similarity\r\n- transformers\r\n- mteb\r\nlicense: mit\r\nlanguage:\r\n- en\r\n---\r\n\r\n\r\nThis is a fork from [BAAI\/bge-base-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-base-en-v1.5) and exported to onnx for inference.\r\n\r\n=======\r\n\r\n\r\n<h1 align=\"center\">FlagEmbedding<\/h1>\r\n\r\n\r\n<h4 align=\"center\">\r\n    <p>\r\n        <a href=#model-list>Model List<\/a> | \r\n        <a href=#frequently-asked-questions>FAQ<\/a> |\r\n        <a href=#usage>Usage<\/a>  |\r\n        <a href=\"#evaluation\">Evaluation<\/a> |\r\n        <a href=\"#train\">Train<\/a> |\r\n        <a href=\"#contact\">Contact<\/a> |\r\n        <a href=\"#citation\">Citation<\/a> |\r\n        <a href=\"#license\">License<\/a> \r\n    <p>\r\n<\/h4>\r\n\r\nMore details please refer to our Github: [FlagEmbedding](https:\/\/github.com\/FlagOpen\/FlagEmbedding).\r\n\r\n\r\n[English](README.md) | [\u4E2D\u6587](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/README_zh.md)\r\n\r\nFlagEmbedding can map any text to a low-dimensional dense vector which can be used for tasks like retrieval, classification,  clustering, or semantic search.\r\nAnd it also can be used in vector databases for LLMs.\r\n\r\n************* \uD83C\uDF1F**Updates**\uD83C\uDF1F *************\r\n- 09\/15\/2023: Release [paper](https:\/\/arxiv.org\/pdf\/2309.07597.pdf) and [dataset](https:\/\/data.baai.ac.cn\/details\/BAAI-MTP).\r\n- 09\/12\/2023: New Release: \r\n    - **New reranker model**: release cross-encoder models `BAAI\/bge-reranker-base` and `BAAI\/bge-reranker-large`, which are more powerful than embedding model. We recommend to use\/fine-tune them to re-rank top-k documents returned by embedding models. \r\n    - **update embedding model**: release `bge-*-v1.5` embedding model to alleviate the issue of the similarity distribution, and enhance its retrieval ability without instruction.\r\n- 09\/07\/2023: Update [fine-tune code](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/FlagEmbedding\/baai_general_embedding\/README.md): Add script to mine hard negatives and support adding instruction during fine-tuning.\r\n- 08\/09\/2023: BGE Models are integrated into **Langchain**, you can use it like [this](#using-langchain); C-MTEB **leaderboard** is [available](https:\/\/huggingface.co\/spaces\/mteb\/leaderboard).  \r\n- 08\/05\/2023: Release base-scale and small-scale models, **best performance among the models of the same size \uD83E\uDD17**\r\n- 08\/02\/2023: Release `bge-large-*`(short for BAAI General Embedding) Models, **rank 1st on MTEB and C-MTEB benchmark!** :tada: :tada: \r\n- 08\/01\/2023: We release the [Chinese Massive Text Embedding Benchmark](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/C_MTEB) (**C-MTEB**), consisting of 31 test dataset.   \r\n\r\n\r\n## Model List\r\n\r\n`bge` is short for `BAAI general embedding`.\r\n\r\n|              Model              | Language | | Description | query instruction for retrieval\\* |\r\n|:-------------------------------|:--------:| :--------:| :--------:|:--------:|\r\n|  [BAAI\/bge-reranker-large](https:\/\/huggingface.co\/BAAI\/bge-reranker-large) |   Chinese and English | [Inference](#usage-for-reranker) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/reranker) | a cross-encoder model which is more accurate but less efficient \\** |   |\r\n|  [BAAI\/bge-reranker-base](https:\/\/huggingface.co\/BAAI\/bge-reranker-base) |   Chinese and English | [Inference](#usage-for-reranker) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/reranker) | a cross-encoder model which is more accurate but less efficient \\** |   |\r\n|  [BAAI\/bge-large-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-large-en-v1.5) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-base-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-base-en-v1.5) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-small-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-small-en-v1.5) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution  | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-large-zh-v1.5](https:\/\/huggingface.co\/BAAI\/bge-large-zh-v1.5) |   Chinese | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n|  [BAAI\/bge-base-zh-v1.5](https:\/\/huggingface.co\/BAAI\/bge-base-zh-v1.5) |   Chinese |  [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n|  [BAAI\/bge-small-zh-v1.5](https:\/\/huggingface.co\/BAAI\/bge-small-zh-v1.5) |   Chinese | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | version 1.5 with more reasonable similarity distribution | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n|  [BAAI\/bge-large-en](https:\/\/huggingface.co\/BAAI\/bge-large-en) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | :trophy: rank **1st** in [MTEB](https:\/\/huggingface.co\/spaces\/mteb\/leaderboard) leaderboard | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-base-en](https:\/\/huggingface.co\/BAAI\/bge-base-en) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | a base-scale model but with similar ability to `bge-large-en` | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-small-en](https:\/\/huggingface.co\/BAAI\/bge-small-en) |   English | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) |a small-scale model but with competitive performance  | `Represent this sentence for searching relevant passages: `  |\r\n|  [BAAI\/bge-large-zh](https:\/\/huggingface.co\/BAAI\/bge-large-zh) |   Chinese | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | :trophy: rank **1st** in [C-MTEB](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/C_MTEB) benchmark | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n|  [BAAI\/bge-base-zh](https:\/\/huggingface.co\/BAAI\/bge-base-zh) |   Chinese |  [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | a base-scale model but with similar ability to `bge-large-zh` | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n|  [BAAI\/bge-small-zh](https:\/\/huggingface.co\/BAAI\/bge-small-zh) |   Chinese | [Inference](#usage-for-embedding-model) [Fine-tune](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) | a small-scale model but with competitive performance | `\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A`  |\r\n\r\n\r\n\\*: If you need to search the relevant passages to a query, we suggest to add the instruction to the query; in other cases, no instruction is needed, just use the original query directly. In all cases, **no instruction** needs to be added to passages.\r\n\r\n\\**: Different from embedding model, reranker uses question and document as input and directly output similarity instead of embedding. To balance the accuracy and time cost, cross-encoder is widely used to re-rank top-k documents retrieved by other simple models. \r\nFor examples, use bge embedding model to retrieve top 100 relevant documents, and then use bge reranker to re-rank the top 100 document to get the final top-3 results.\r\n\r\n## Frequently asked questions\r\n\r\n<details>\r\n  <summary>1. How to fine-tune bge embedding model?<\/summary>\r\n\r\n  <!-- ### How to fine-tune bge embedding model? -->\r\nFollowing this [example](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune) to prepare data and fine-tune your model. \r\nSome suggestions:\r\n- Mine hard negatives following this [example](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune#hard-negatives), which can improve the retrieval performance.\r\n- If you pre-train bge on your data, the pre-trained model cannot be directly used to calculate similarity, and it must be fine-tuned with contrastive learning before computing similarity.\r\n- If the accuracy of the fine-tuned model is still not high, it is recommended to use\/fine-tune the cross-encoder model (bge-reranker) to re-rank top-k results. Hard negatives also are needed to fine-tune reranker.\r\n\r\n  \r\n<\/details>\r\n\r\n<details>\r\n  <summary>2. The similarity score between two dissimilar sentences is higher than 0.5<\/summary>\r\n\r\n  <!-- ### The similarity score between two dissimilar sentences is higher than 0.5 -->\r\n**Suggest to use bge v1.5, which alleviates the issue of the similarity distribution.** \r\n\r\nSince we finetune the models by contrastive learning with a temperature of 0.01, \r\nthe similarity distribution of the current BGE model is about in the interval \\[0.6, 1\\].\r\nSo a similarity score greater than 0.5 does not indicate that the two sentences are similar.\r\n\r\nFor downstream tasks, such as passage retrieval or semantic similarity, \r\n**what matters is the relative order of the scores, not the absolute value.**\r\nIf you need to filter similar sentences based on a similarity threshold, \r\nplease select an appropriate similarity threshold based on the similarity distribution on your data (such as 0.8, 0.85, or even 0.9).\r\n\r\n<\/details>\r\n\r\n<details>\r\n  <summary>3. When does the query instruction need to be used<\/summary>\r\n\r\n  <!-- ### When does the query instruction need to be used -->\r\n  \r\nFor a retrieval task that uses short queries to find long related documents, \r\nit is recommended to add instructions for these short queries.\r\n**The best method to decide whether to add instructions for queries is choosing the setting that achieves better performance on your task.**\r\nIn all cases, the documents\/passages do not need to add the instruction. \r\n\r\n<\/details>\r\n\r\n\r\n## Usage \r\n\r\n### Usage for Embedding Model\r\n\r\nHere are some examples for using `bge` models with \r\n[FlagEmbedding](#using-flagembedding), [Sentence-Transformers](#using-sentence-transformers), [Langchain](#using-langchain), or [Huggingface Transformers](#using-huggingface-transformers).\r\n\r\n#### Using FlagEmbedding\r\n```\r\npip install -U FlagEmbedding\r\n```\r\nIf it doesn'\''t work for you, you can see [FlagEmbedding](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/FlagEmbedding\/baai_general_embedding\/README.md) for more methods to install FlagEmbedding.\r\n\r\n```python\r\nfrom FlagEmbedding import FlagModel\r\nsentences_1 = [\"\u6837\u4F8B\u6570\u636E-1\", \"\u6837\u4F8B\u6570\u636E-2\"]\r\nsentences_2 = [\"\u6837\u4F8B\u6570\u636E-3\", \"\u6837\u4F8B\u6570\u636E-4\"]\r\nmodel = FlagModel('\''BAAI\/bge-large-zh-v1.5'\'', \r\n                  query_instruction_for_retrieval=\"\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A\",\r\n                  use_fp16=True) # Setting use_fp16 to True speeds up computation with a slight performance degradation\r\nembeddings_1 = model.encode(sentences_1)\r\nembeddings_2 = model.encode(sentences_2)\r\nsimilarity = embeddings_1 @ embeddings_2.T\r\nprint(similarity)\r\n\r\n# for s2p(short query to long passage) retrieval task, suggest to use encode_queries() which will automatically add the instruction to each query\r\n# corpus in retrieval task can still use encode() or encode_corpus(), since they don'\''t need instruction\r\nqueries = ['\''query_1'\'', '\''query_2'\'']\r\npassages = [\"\u6837\u4F8B\u6587\u6863-1\", \"\u6837\u4F8B\u6587\u6863-2\"]\r\nq_embeddings = model.encode_queries(queries)\r\np_embeddings = model.encode(passages)\r\nscores = q_embeddings @ p_embeddings.T\r\n```\r\nFor the value of the argument `query_instruction_for_retrieval`, see [Model List](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master#model-list). \r\n\r\nBy default, FlagModel will use all available GPUs when encoding. Please set `os.environ[\"CUDA_VISIBLE_DEVICES\"]` to select specific GPUs.\r\nYou also can set `os.environ[\"CUDA_VISIBLE_DEVICES\"]=\"\"` to make all GPUs unavailable.\r\n\r\n\r\n#### Using Sentence-Transformers\r\n\r\nYou can also use the `bge` models with [sentence-transformers](https:\/\/www.SBERT.net):\r\n\r\n```\r\npip install -U sentence-transformers\r\n```\r\n```python\r\nfrom sentence_transformers import SentenceTransformer\r\nsentences_1 = [\"\u6837\u4F8B\u6570\u636E-1\", \"\u6837\u4F8B\u6570\u636E-2\"]\r\nsentences_2 = [\"\u6837\u4F8B\u6570\u636E-3\", \"\u6837\u4F8B\u6570\u636E-4\"]\r\nmodel = SentenceTransformer('\''BAAI\/bge-large-zh-v1.5'\'')\r\nembeddings_1 = model.encode(sentences_1, normalize_embeddings=True)\r\nembeddings_2 = model.encode(sentences_2, normalize_embeddings=True)\r\nsimilarity = embeddings_1 @ embeddings_2.T\r\nprint(similarity)\r\n```\r\nFor s2p(short query to long passage) retrieval task, \r\neach short query should start with an instruction (instructions see [Model List](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master#model-list)). \r\nBut the instruction is not needed for passages.\r\n```python\r\nfrom sentence_transformers import SentenceTransformer\r\nqueries = ['\''query_1'\'', '\''query_2'\'']\r\npassages = [\"\u6837\u4F8B\u6587\u6863-1\", \"\u6837\u4F8B\u6587\u6863-2\"]\r\ninstruction = \"\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A\"\r\n\r\nmodel = SentenceTransformer('\''BAAI\/bge-large-zh-v1.5'\'')\r\nq_embeddings = model.encode([instruction+q for q in queries], normalize_embeddings=True)\r\np_embeddings = model.encode(passages, normalize_embeddings=True)\r\nscores = q_embeddings @ p_embeddings.T\r\n```\r\n\r\n#### Using Langchain \r\n\r\nYou can use `bge` in langchain like this:\r\n```python\r\nfrom langchain.embeddings import HuggingFaceBgeEmbeddings\r\nmodel_name = \"BAAI\/bge-large-en-v1.5\"\r\nmodel_kwargs = {'\''device'\'': '\''cuda'\''}\r\nencode_kwargs = {'\''normalize_embeddings'\'': True} # set True to compute cosine similarity\r\nmodel = HuggingFaceBgeEmbeddings(\r\n    model_name=model_name,\r\n    model_kwargs=model_kwargs,\r\n    encode_kwargs=encode_kwargs,\r\n    query_instruction=\"\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A\"\r\n)\r\nmodel.query_instruction = \"\u4E3A\u8FD9\u4E2A\u53E5\u5B50\u751F\u6210\u8868\u793A\u4EE5\u7528\u4E8E\u68C0\u7D22\u76F8\u5173\u6587\u7AE0\uFF1A\"\r\n```\r\n\r\n\r\n#### Using HuggingFace Transformers\r\n\r\nWith the transformers package, you can use the model like this: First, you pass your input through the transformer model, then you select the last hidden state of the first token (i.e., [CLS]) as the sentence embedding.\r\n\r\n```python\r\nfrom transformers import AutoTokenizer, AutoModel\r\nimport torch\r\n# Sentences we want sentence embeddings for\r\nsentences = [\"\u6837\u4F8B\u6570\u636E-1\", \"\u6837\u4F8B\u6570\u636E-2\"]\r\n\r\n# Load model from HuggingFace Hub\r\ntokenizer = AutoTokenizer.from_pretrained('\''BAAI\/bge-large-zh-v1.5'\'')\r\nmodel = AutoModel.from_pretrained('\''BAAI\/bge-large-zh-v1.5'\'')\r\nmodel.eval()\r\n\r\n# Tokenize sentences\r\nencoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='\''pt'\'')\r\n# for s2p(short query to long passage) retrieval task, add an instruction to query (not add instruction for passages)\r\n# encoded_input = tokenizer([instruction + q for q in queries], padding=True, truncation=True, return_tensors='\''pt'\'')\r\n\r\n# Compute token embeddings\r\nwith torch.no_grad():\r\n    model_output = model(**encoded_input)\r\n    # Perform pooling. In this case, cls pooling.\r\n    sentence_embeddings = model_output[0][:, 0]\r\n# normalize embeddings\r\nsentence_embeddings = torch.nn.functional.normalize(sentence_embeddings, p=2, dim=1)\r\nprint(\"Sentence embeddings:\", sentence_embeddings)\r\n```\r\n\r\n### Usage for Reranker\r\n\r\nDifferent from embedding model, reranker uses question and document as input and directly output similarity instead of embedding. \r\nYou can get a relevance score by inputting query and passage to the reranker. \r\nThe reranker is optimized based cross-entropy loss, so the relevance score is not bounded to a specific range.\r\n\r\n\r\n#### Using FlagEmbedding\r\n```\r\npip install -U FlagEmbedding\r\n```\r\n\r\nGet relevance scores (higher scores indicate more relevance):\r\n```python\r\nfrom FlagEmbedding import FlagReranker\r\nreranker = FlagReranker('\''BAAI\/bge-reranker-large'\'', use_fp16=True) # Setting use_fp16 to True speeds up computation with a slight performance degradation\r\n\r\nscore = reranker.compute_score(['\''query'\'', '\''passage'\''])\r\nprint(score)\r\n\r\nscores = reranker.compute_score([['\''what is panda?'\'', '\''hi'\''], ['\''what is panda?'\'', '\''The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.'\'']])\r\nprint(scores)\r\n```\r\n\r\n\r\n#### Using Huggingface transformers\r\n\r\n```python\r\nimport torch\r\nfrom transformers import AutoModelForSequenceClassification, AutoTokenizer\r\n\r\ntokenizer = AutoTokenizer.from_pretrained('\''BAAI\/bge-reranker-large'\'')\r\nmodel = AutoModelForSequenceClassification.from_pretrained('\''BAAI\/bge-reranker-large'\'')\r\nmodel.eval()\r\n\r\npairs = [['\''what is panda?'\'', '\''hi'\''], ['\''what is panda?'\'', '\''The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.'\'']]\r\nwith torch.no_grad():\r\n    inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors='\''pt'\'', max_length=512)\r\n    scores = model(**inputs, return_dict=True).logits.view(-1, ).float()\r\n    print(scores)\r\n```\r\n\r\n## Evaluation  \r\n\r\n`baai-general-embedding` models achieve **state-of-the-art performance on both MTEB and C-MTEB leaderboard!**\r\nFor more details and evaluation tools see our [scripts](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/C_MTEB\/README.md). \r\n\r\n- **MTEB**:   \r\n\r\n| Model Name |  Dimension | Sequence Length | Average (56) | Retrieval (15) |Clustering (11) | Pair Classification (3) | Reranking (4) |  STS (10) | Summarization (1) | Classification (12) |\r\n|:----:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\r\n| [BAAI\/bge-large-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-large-en-v1.5) | 1024 | 512 |  **64.23** | **54.29** |  46.08 | 87.12 | 60.03 | 83.11 | 31.61 | 75.97 |  \r\n| [BAAI\/bge-base-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-base-en-v1.5) |  768 | 512 | 63.55 | 53.25 |   45.77 | 86.55 | 58.86 | 82.4 | 31.07 | 75.53 |  \r\n| [BAAI\/bge-small-en-v1.5](https:\/\/huggingface.co\/BAAI\/bge-small-en-v1.5) |  384 | 512 | 62.17 |51.68 | 43.82 |  84.92 | 58.36 | 81.59 | 30.12 | 74.14 |  \r\n| [bge-large-en](https:\/\/huggingface.co\/BAAI\/bge-large-en) |  1024 | 512 | 63.98 |  53.9 | 46.98 | 85.8 | 59.48 | 81.56 | 32.06 | 76.21 | \r\n| [bge-base-en](https:\/\/huggingface.co\/BAAI\/bge-base-en) |  768 | 512 |  63.36 | 53.0 | 46.32 | 85.86 | 58.7 | 81.84 | 29.27 | 75.27 | \r\n| [gte-large](https:\/\/huggingface.co\/thenlper\/gte-large) |  1024 | 512 | 63.13 | 52.22 | 46.84 | 85.00 | 59.13 | 83.35 | 31.66 | 73.33 |\r\n| [gte-base](https:\/\/huggingface.co\/thenlper\/gte-base) \t|  768 | 512 | 62.39 | 51.14 | 46.2 | 84.57 | 58.61 | 82.3 | 31.17 | 73.01 |\r\n| [e5-large-v2](https:\/\/huggingface.co\/intfloat\/e5-large-v2) |  1024| 512 | 62.25 | 50.56 | 44.49 | 86.03 | 56.61 | 82.05 | 30.19 | 75.24 |\r\n| [bge-small-en](https:\/\/huggingface.co\/BAAI\/bge-small-en) |  384 | 512 | 62.11 |  51.82 | 44.31 | 83.78 | 57.97 | 80.72 | 30.53 | 74.37 |  \r\n| [instructor-xl](https:\/\/huggingface.co\/hkunlp\/instructor-xl) |  768 | 512 | 61.79 | 49.26 | 44.74 | 86.62 | 57.29 | 83.06 | 32.32 | 61.79 |\r\n| [e5-base-v2](https:\/\/huggingface.co\/intfloat\/e5-base-v2) |  768 | 512 | 61.5 | 50.29 | 43.80 | 85.73 | 55.91 | 81.05 | 30.28 | 73.84 |\r\n| [gte-small](https:\/\/huggingface.co\/thenlper\/gte-small) |  384 | 512 | 61.36 | 49.46 | 44.89 | 83.54 | 57.7 | 82.07 | 30.42 | 72.31 |\r\n| [text-embedding-ada-002](https:\/\/platform.openai.com\/docs\/guides\/embeddings) | 1536 | 8192 | 60.99 | 49.25 | 45.9 | 84.89 | 56.32 | 80.97 | 30.8 | 70.93 |\r\n| [e5-small-v2](https:\/\/huggingface.co\/intfloat\/e5-base-v2) | 384 | 512 | 59.93 | 49.04 | 39.92 | 84.67 | 54.32 | 80.39 | 31.16 | 72.94 |\r\n| [sentence-t5-xxl](https:\/\/huggingface.co\/sentence-transformers\/sentence-t5-xxl) |  768 | 512 | 59.51 | 42.24 | 43.72 | 85.06 | 56.42 | 82.63 | 30.08 | 73.42 |\r\n| [all-mpnet-base-v2](https:\/\/huggingface.co\/sentence-transformers\/all-mpnet-base-v2) \t|  768 | 514 \t| 57.78 | 43.81 | 43.69 | 83.04 | 59.36 | 80.28 | 27.49 | 65.07 |\r\n| [sgpt-bloom-7b1-msmarco](https:\/\/huggingface.co\/bigscience\/sgpt-bloom-7b1-msmarco) \t|  4096 | 2048 | 57.59 | 48.22 | 38.93 | 81.9 | 55.65 | 77.74 | 33.6 | 66.19 |\r\n\r\n\r\n\r\n- **C-MTEB**:  \r\nWe create the benchmark C-MTEB for Chinese text embedding which consists of 31 datasets from 6 tasks. \r\nPlease refer to [C_MTEB](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/C_MTEB\/README.md) for a detailed introduction.\r\n \r\n| Model | Embedding dimension | Avg | Retrieval | STS | PairClassification | Classification | Reranking | Clustering |\r\n|:-------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|\r\n| [**BAAI\/bge-large-zh-v1.5**](https:\/\/huggingface.co\/BAAI\/bge-large-zh-v1.5) | 1024 |  **64.53** | 70.46 | 56.25 | 81.6 | 69.13 | 65.84 | 48.99 |  \r\n| [BAAI\/bge-base-zh-v1.5](https:\/\/huggingface.co\/BAAI\/bge-base-zh-v1.5) | 768 |  63.13 | 69.49 | 53.72 | 79.75 | 68.07 | 65.39 | 47.53 |  \r\n| [BAAI\/bge-small-zh-v1.5](https:\/\/huggingface.co\/BAAI\/bge-small-zh-v1.5) | 512 | 57.82 | 61.77 | 49.11 | 70.41 | 63.96 | 60.92 | 44.18 |   \r\n| [BAAI\/bge-large-zh](https:\/\/huggingface.co\/BAAI\/bge-large-zh) | 1024 | 64.20 | 71.53 | 54.98 | 78.94 | 68.32 | 65.11 | 48.39 |\r\n| [bge-large-zh-noinstruct](https:\/\/huggingface.co\/BAAI\/bge-large-zh-noinstruct) | 1024 | 63.53 | 70.55 | 53 | 76.77 | 68.58 | 64.91 | 50.01 |\r\n| [BAAI\/bge-base-zh](https:\/\/huggingface.co\/BAAI\/bge-base-zh) | 768 | 62.96 | 69.53 | 54.12 | 77.5 | 67.07 | 64.91 | 47.63 |\r\n| [multilingual-e5-large](https:\/\/huggingface.co\/intfloat\/multilingual-e5-large) | 1024 | 58.79 | 63.66 | 48.44 | 69.89 | 67.34 | 56.00 | 48.23 |\r\n| [BAAI\/bge-small-zh](https:\/\/huggingface.co\/BAAI\/bge-small-zh) | 512 | 58.27 |  63.07 | 49.45 | 70.35 | 63.64 | 61.48 | 45.09 |\r\n| [m3e-base](https:\/\/huggingface.co\/moka-ai\/m3e-base) | 768 | 57.10 | 56.91 | 50.47 | 63.99 | 67.52 | 59.34 | 47.68 |\r\n| [m3e-large](https:\/\/huggingface.co\/moka-ai\/m3e-large) | 1024 |  57.05 | 54.75 | 50.42 | 64.3 | 68.2 | 59.66 | 48.88 |\r\n| [multilingual-e5-base](https:\/\/huggingface.co\/intfloat\/multilingual-e5-base) | 768 | 55.48 | 61.63 | 46.49 | 67.07 | 65.35 | 54.35 | 40.68 |\r\n| [multilingual-e5-small](https:\/\/huggingface.co\/intfloat\/multilingual-e5-small) | 384 | 55.38 | 59.95 | 45.27 | 66.45 | 65.85 | 53.86 | 45.26 |\r\n| [text-embedding-ada-002(OpenAI)](https:\/\/platform.openai.com\/docs\/guides\/embeddings\/what-are-embeddings) | 1536 |  53.02 | 52.0 | 43.35 | 69.56 | 64.31 | 54.28 | 45.68 |\r\n| [luotuo](https:\/\/huggingface.co\/silk-road\/luotuo-bert-medium) | 1024 | 49.37 |  44.4 | 42.78 | 66.62 | 61 | 49.25 | 44.39 |\r\n| [text2vec-base](https:\/\/huggingface.co\/shibing624\/text2vec-base-chinese) | 768 |  47.63 | 38.79 | 43.41 | 67.41 | 62.19 | 49.45 | 37.66 |\r\n| [text2vec-large](https:\/\/huggingface.co\/GanymedeNil\/text2vec-large-chinese) | 1024 | 47.36 | 41.94 | 44.97 | 70.86 | 60.66 | 49.16 | 30.02 |\r\n\r\n\r\n- **Reranking**:\r\nSee [C_MTEB](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/C_MTEB\/) for evaluation script.\r\n\r\n| Model | T2Reranking | T2RerankingZh2En\\* | T2RerankingEn2Zh\\* | MMarcoReranking | CMedQAv1 | CMedQAv2 | Avg |  \r\n|:-------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|  \r\n| text2vec-base-multilingual | 64.66 | 62.94 | 62.51 | 14.37 | 48.46 | 48.6 | 50.26 |  \r\n| multilingual-e5-small | 65.62 | 60.94 | 56.41 | 29.91 | 67.26 | 66.54 | 57.78 |  \r\n| multilingual-e5-large | 64.55 | 61.61 | 54.28 | 28.6 | 67.42 | 67.92 | 57.4 |  \r\n| multilingual-e5-base | 64.21 | 62.13 | 54.68 | 29.5 | 66.23 | 66.98 | 57.29 |  \r\n| m3e-base | 66.03 | 62.74 | 56.07 | 17.51 | 77.05 | 76.76 | 59.36 |  \r\n| m3e-large | 66.13 | 62.72 | 56.1 | 16.46 | 77.76 | 78.27 | 59.57 |  \r\n| bge-base-zh-v1.5 | 66.49 | 63.25 | 57.02 | 29.74 | 80.47 | 84.88 | 63.64 |  \r\n| bge-large-zh-v1.5 | 65.74 | 63.39 | 57.03 | 28.74 | 83.45 | 85.44 | 63.97 |  \r\n| [BAAI\/bge-reranker-base](https:\/\/huggingface.co\/BAAI\/bge-reranker-base) | 67.28 | 63.95 | 60.45 | 35.46 | 81.26 | 84.1 | 65.42 |  \r\n| [BAAI\/bge-reranker-large](https:\/\/huggingface.co\/BAAI\/bge-reranker-large) | 67.6 | 64.03 | 61.44 | 37.16 | 82.15 | 84.18 | 66.09 |  \r\n\r\n\\* : T2RerankingZh2En and T2RerankingEn2Zh are cross-language retrieval tasks\r\n\r\n## Train\r\n\r\n### BAAI Embedding \r\n\r\nWe pre-train the models using [retromae](https:\/\/github.com\/staoxiao\/RetroMAE) and train them on large-scale pairs data using contrastive learning. \r\n**You can fine-tune the embedding model on your data following our [examples](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/finetune).**\r\nWe also provide a [pre-train example](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/pretrain).\r\nNote that the goal of pre-training is to reconstruct the text, and the pre-trained model cannot be used for similarity calculation directly, it needs to be fine-tuned.\r\nMore training details for bge see [baai_general_embedding](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/FlagEmbedding\/baai_general_embedding\/README.md).\r\n\r\n\r\n\r\n### BGE Reranker\r\n\r\nCross-encoder will perform full-attention over the input pair, \r\nwhich is more accurate than embedding model (i.e., bi-encoder) but more time-consuming than embedding model.\r\nTherefore, it can be used to re-rank the top-k documents returned by embedding model.\r\nWe train the cross-encoder on a multilingual pair data, \r\nThe data format is the same as embedding model, so you can fine-tune it easily following our [example](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/examples\/reranker). \r\nMore details pelease refer to [.\/FlagEmbedding\/reranker\/README.md](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/tree\/master\/FlagEmbedding\/reranker)\r\n\r\n\r\n## Contact\r\nIf you have any question or suggestion related to this project, feel free to open an issue or pull request.\r\nYou also can email Shitao Xiao([email protected]) and Zheng Liu([email protected]). \r\n\r\n\r\n## Citation\r\n\r\nIf you find our work helpful, please cite us:\r\n```\r\n@misc{bge_embedding,\r\n      title={C-Pack: Packaged Resources To Advance General Chinese Embedding}, \r\n      author={Shitao Xiao and Zheng Liu and Peitian Zhang and Niklas Muennighoff},\r\n      year={2023},\r\n      eprint={2309.07597},\r\n      archivePrefix={arXiv},\r\n      primaryClass={cs.CL}\r\n}\r\n```\r\n\r\n## License\r\nFlagEmbedding is licensed under the [MIT License](https:\/\/github.com\/FlagOpen\/FlagEmbedding\/blob\/master\/LICENSE). The released models can be used for commercial purposes free of charge.\r\n",
  "name": "big-descr"
}'

when using a big description, and noticed if using Markdown in a description fails with syntax error:

<_InactiveRpcError of RPC that terminated with:
	status = StatusCode.INTERNAL
	details = "PostgreSQL metadata source error: ERROR:  syntax error at or near "This"
LINE 1: ...tring_value ) VALUES(15, 'description', FALSE, 'E'This is a ...
                                                             ^
"
	debug_error_string = "UNKNOWN:Error received from peer  {created_time:"2024-01-08T10:10:25.971153166+00:00", grpc_status:13, grpc_message:"PostgreSQL metadata source error: ERROR:  syntax error at or near \"This\"\nLINE 1: ...tring_value ) VALUES(15, \'description\', FALSE, \'E\'This is a ...\n                                                             ^\n"}"
>

edit: can be replicated beyond MR python client with REST using:

curl -X 'POST' \
  'https://mr-secure-ds-mre2e.apps.rosa.mmortari-rosa-h.w0x4.p3.openshiftapps.com/api/model_registry/v1alpha1/registered_models' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eget dolor non risus tempus semper. Aliquam sit amet tincidunt nisl. In feugiat mattis elit vitae accumsan. Mauris facilisis maximus nisl et molestie. Quisque a nibh dictum, facilisis purus at, dictum velit. Vivamus et erat ac magna pellentesque dictum. Mauris vel mauris sagittis risus bibendum aliquam. Sed vestibulum efficitur odio at dapibus. Phasellus ac tempor turpis.\r\n\r\nNam nec magna eu tellus varius pretium eu quis massa. Quisque elit diam, faucibus id leo sit amet, varius cursus tortor. Vestibulum ut justo sed velit volutpat varius. Morbi pretium odio lacinia risus ultricies efficitur. Fusce iaculis, quam non placerat malesuada, mauris neque fermentum dui, nec sodales urna erat ac eros. Nulla ullamcorper quam at metus molestie, non luctus erat molestie. Duis id laoreet arcu, faucibus porttitor enim. Phasellus tristique dolor et justo tincidunt, ut ultrices tellus sodales. Fusce velit risus, euismod sit amet porta mollis, tempor viverra sapien. Sed eget diam a lacus mollis molestie. Quisque molestie suscipit vehicula. Nunc bibendum porttitor orci, in iaculis nibh. Aenean lacinia, risus sed condimentum accumsan, erat est mattis est, sit amet mollis dui eros eu eros. Pellentesque eget tortor nunc. Etiam quis mauris non mauris pellentesque hendrerit sed non turpis.\r\n\r\nSed accumsan aliquam urna, eu maximus est viverra eleifend. Sed sit amet felis molestie nunc facilisis suscipit sit amet sit amet nulla. Vivamus libero leo, facilisis non euismod at, iaculis fringilla ex. Maecenas finibus nulla in volutpat vestibulum. Nam nibh purus, consequat eget nisi eget, consectetur iaculis lacus. In eget rhoncus felis. Morbi et mi id neque viverra rhoncus at eget ante. Integer sagittis volutpat augue ac auctor. Suspendisse vel gravida justo. Duis eget turpis tristique nunc mattis ullamcorper. In non euismod sapien. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam ultricies ligula ac mattis efficitur. Vestibulum id sollicitudin lorem, ac fermentum elit. Curabitur porttitor quis dui a accumsan.\r\n\r\nVivamus in leo facilisis, consectetur lorem non, eleifend mauris. Vestibulum ultrices quam quam, eu suscipit nisl sollicitudin sed. Ut ac scelerisque quam. Aliquam vel ultricies lorem. Aenean mattis nulla ut libero congue sodales. Proin dolor purus, malesuada pellentesque iaculis ac, volutpat mattis lorem. Aliquam et sapien sem. Curabitur facilisis blandit vulputate. Donec rhoncus urna sit amet orci convallis, at porttitor massa convallis. Ut lobortis felis in massa malesuada, at consectetur leo tincidunt. Pellentesque et ex non enim ultricies bibendum ut at justo. Nulla non sodales elit, euismod ultricies mauris. Phasellus purus metus, condimentum porttitor tristique quis, sollicitudin sit amet mauris. Nulla convallis luctus quam ac cursus. Ut a ligula vitae odio suscipit tempor in eget ipsum. Nullam pulvinar, ligula sit amet bibendum eleifend, enim est pulvinar libero, sit amet cursus purus nunc at enim.\r\n\r\nMauris luctus ante tempus velit egestas tempus. Etiam vitae ultrices mi. Sed a aliquam lorem, vel facilisis quam. Donec imperdiet in nunc nec malesuada. Nullam cursus tempor mi id elementum. In hac habitasse platea dictumst. Nunc varius mauris orci, a commodo ipsum ornare at. Phasellus feugiat elementum tincidunt. Aliquam malesuada pellentesque est quis interdum. Quisque finibus faucibus sem eget ullamcorper. Etiam aliquet vel nunc et eleifend. Donec id mi eu tortor finibus posuere sit amet et augue. Duis efficitur volutpat vestibulum. Sed urna ipsum, sagittis id dignissim a, suscipit nec odio.\r\n\r\nSed eu ullamcorper ligula. Quisque dictum convallis libero, at commodo purus commodo hendrerit. Morbi ultrices sapien ut augue varius gravida. Fusce semper facilisis elit, vitae convallis ipsum dapibus nec. Proin vitae augue eget diam volutpat tristique cursus a ex. Sed erat metus, ullamcorper a dapibus sed, blandit a arcu. Pellentesque eros eros, pulvinar at quam nec, consequat vestibulum leo. Pellentesque nibh velit, faucibus quis est ut, elementum ultrices massa. Pellentesque non finibus quam. Nullam tellus sapien, sagittis non risus quis, finibus viverra dolor. In nec orci vitae nunc ultrices interdum non eu ante. Suspendisse bibendum tellus eu tincidunt molestie. Maecenas pharetra cursus varius. In ultrices sed lectus blandit dignissim. Integer ac fringilla leo. Aenean sit amet pretium lacus.\r\n\r\nFusce vitae dictum nibh. Fusce bibendum, justo vitae fringilla aliquam, augue nulla bibendum lorem, ut egestas augue turpis nec lacus. Aliquam tellus metus, rutrum sit amet lectus sed, molestie dignissim tortor. Pellentesque et lectus id nulla tempus aliquet. Etiam sodales dignissim sagittis. Vivamus ullamcorper odio ac urna aliquam, quis posuere nisl rutrum. Proin finibus nisi non lorem rhoncus, ut feugiat orci imperdiet. Pellentesque ut tortor tortor. In hac habitasse platea dictumst. Nulla facilisi. Cras venenatis blandit dolor quis ullamcorper. Nulla tempus purus quis nibh dictum ornare.\r\n\r\nAenean non tellus vitae odio egestas fermentum quis sit amet massa. Morbi euismod venenatis dictum. Nullam ac fermentum sem, at semper sem. Vivamus sed magna sodales, aliquet sem eu, lacinia mauris. Nulla tempor et tortor sed ultricies. Praesent quis justo nunc. Phasellus eleifend eros nunc, quis pellentesque libero hendrerit tristique. Quisque finibus hendrerit varius. Nam consequat tellus justo, in imperdiet lorem malesuada eu. Nunc non facilisis magna. Integer quam sem, viverra quis massa nec, mollis luctus velit. Aliquam non feugiat erat, sed hendrerit ante. Suspendisse auctor convallis enim, in placerat ex fermentum quis.\r\n\r\nCurabitur nec massa nulla. Aliquam venenatis magna et odio dictum vehicula. Aenean luctus tristique enim, ut aliquam ligula pharetra id. Nullam nec nibh pretium, dictum velit vitae, rutrum lacus. Suspendisse pharetra porta justo at ornare. Praesent nec lectus posuere, imperdiet sapien nec, semper lorem. Donec sit amet euismod nisl.\r\n\r\nSed luctus consequat elit, et elementum metus tincidunt vitae. Phasellus blandit, lacus a lobortis tempus, quam lacus lobortis eros, in consectetur urna lectus in elit. Sed vel ex nibh. In congue elementum enim. Cras maximus nisl in libero aliquam hendrerit vel non justo. Morbi nibh metus, posuere ac pulvinar in, congue quis velit. Aenean non risus at purus gravida bibendum eu sit amet lorem. Nam imperdiet ut sapien eget bibendum. Pellentesque nisl nunc, ultricies sed sapien et, fringilla commodo metus. Sed mollis, eros non ornare mattis, erat dui iaculis risus, ac pretium elit ante in turpis. Vestibulum nec venenatis dui, eu posuere magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut efficitur, ante at mollis interdum, erat ante viverra turpis, sed placerat sapien leo semper turpis. Sed hendrerit volutpat diam.\r\n\r\nPraesent scelerisque odio non viverra maximus. Mauris a elit diam. Proin in nisl tortor. Cras vel convallis magna. Suspendisse bibendum semper enim eu cursus. Phasellus risus mi, mattis quis leo non, aliquet dapibus nunc. Maecenas congue lobortis diam, eu pellentesque sapien imperdiet ac. Nullam tempor suscipit enim in egestas. Donec dignissim tellus vitae sem malesuada, quis vehicula ipsum bibendum. Mauris iaculis tempus cursus. Etiam venenatis erat magna, vel pulvinar enim accumsan ut. Phasellus sollicitudin velit vitae sapien tempor, a pharetra felis tincidunt. Vivamus lobortis libero nisl, at consequat turpis placerat vitae. Donec nec tellus lectus. Sed rhoncus, turpis eu volutpat tristique, nunc orci luctus sem, nec egestas ex eros at purus.\r\n\r\nEtiam consectetur ornare sem, eget feugiat dolor volutpat sodales. Pellentesque sed finibus justo. Vivamus eu ante dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Vivamus hendrerit orci ante, in ultrices risus pulvinar mollis. Vivamus justo nisi, elementum ut ex ac, semper porta metus. Aliquam id ante ornare nisi dictum tincidunt sed a massa. Quisque sollicitudin finibus cursus. Phasellus sed porttitor dolor, vel ullamcorper sem. Vestibulum vulputate sagittis ligula, eget porttitor elit ultricies id. Nunc vel hendrerit magna. Nulla sed ultrices dolor. Etiam viverra metus at ante dapibus dictum. Nullam tellus nunc, mattis maximus magna tincidunt, iaculis eleifend libero.\r\n\r\nNulla convallis mauris velit, in volutpat lacus mattis eget. Fusce non libero non orci suscipit laoreet non eu sem. Etiam varius cursus diam et molestie. Pellentesque finibus magna vitae massa suscipit, eu feugiat nisi faucibus. Vestibulum consectetur congue lacus, sit amet fringilla tortor iaculis eget. Praesent elementum orci imperdiet sapien pretium tempus. Curabitur nec blandit felis. Cras in pulvinar elit. Nullam ullamcorper gravida sem, at volutpat erat suscipit quis. Integer eu tempor ligula. Aenean ex nunc, lacinia ac lobortis luctus, euismod et massa. Pellentesque in elementum massa, quis molestie arcu. Donec id ultricies nulla.\r\n\r\nProin sollicitudin est orci, eu elementum enim faucibus finibus. Donec vehicula posuere elit, vehicula vehicula felis fringilla id. Donec porta vitae quam ac mattis. Ut sit amet malesuada nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec bibendum lobortis pretium. Quisque eleifend erat metus, non consequat arcu ultrices vitae. Integer volutpat eu neque quis lobortis. Aenean mauris est, vestibulum a ultricies fermentum, cursus et turpis. Nunc non nibh et turpis elementum tristique.\r\n\r\nUt malesuada tellus sit amet erat tincidunt laoreet. Praesent et risus mauris. Suspendisse sit amet arcu porta, cursus lorem feugiat, ullamcorper libero. Cras metus mi, ornare ac lacus et, convallis pellentesque enim. Mauris orci nibh, faucibus non sagittis ac, congue a tortor. Sed at augue sit amet nisi convallis semper tempor id arcu. Suspendisse eget elit et mauris malesuada laoreet at eget lectus. Sed quam enim, viverra et venenatis in, molestie sed nunc. Sed ut odio ac dui imperdiet molestie quis in nisl. Phasellus malesuada elementum magna quis elementum. Etiam lorem nisi, luctus ac orci ac, scelerisque auctor leo.\r\n\r\nSed quis urna id nisl tempus placerat. Aenean eget odio egestas, posuere purus eget, vulputate tellus. Nulla porttitor leo in eros tempus pretium. Aliquam vehicula interdum neque eget dapibus. Praesent commodo orci nisi, quis fermentum nulla convallis vitae. Nam at lacus blandit ligula fermentum vulputate nec vel odio. Ut et blandit eros. Etiam non elit dapibus, dapibus quam vulputate, ullamcorper sem.\r\n\r\nMaecenas eros sem, vestibulum sed lorem vel, tempus mattis sapien. Quisque condimentum, lorem at tempus sagittis, justo orci fermentum dolor, mattis molestie nibh dolor eu arcu. Quisque nulla odio, egestas et congue nec, ornare et magna. Mauris sed sapien bibendum, varius lorem in, cursus quam. Aenean placerat blandit tincidunt. Quisque sit amet sollicitudin velit, vitae pulvinar enim. Nunc mi urna, vestibulum ut velit sed, sollicitudin mollis ipsum.\r\n\r\nNullam imperdiet nulla a velit efficitur tincidunt. Curabitur dignissim placerat feugiat. Integer condimentum hendrerit elementum. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean molestie, neque ut congue tristique, quam nulla faucibus odio, in tempus augue erat pharetra diam. Aliquam tempor tellus ut venenatis accumsan. Donec et arcu at nisi suscipit accumsan quis et dolor. Mauris hendrerit volutpat dui, vel rhoncus felis. Suspendisse quam tortor, ultrices ac gravida non, sagittis ac sem. Maecenas sit amet risus id sapien egestas consequat. Praesent lacinia urna metus, ac volutpat dolor pharetra a. Vivamus viverra accumsan nulla, vitae varius tortor efficitur sed. Fusce ornare lectus vel hendrerit semper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec vel porta dolor.\r\n\r\nUt non eros aliquet, fermentum ipsum non, finibus arcu. Fusce eget pharetra nibh. Duis aliquam massa vel euismod tincidunt. Donec sed aliquet metus, et blandit nunc. Mauris elementum dolor quam, eu vehicula est porttitor vel. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce vitae nulla hendrerit, cursus lorem et, convallis tellus. Ut molestie sem mauris, et scelerisque felis gravida eu. Integer finibus fermentum risus, ac mattis dolor scelerisque sed. Praesent convallis, ex non tempor tempus, sem sem maximus nibh, in scelerisque ex elit sed velit. Sed suscipit vel lectus quis pulvinar. Nam scelerisque tincidunt erat, ac congue erat venenatis vel. Integer scelerisque congue nulla. Sed feugiat massa ligula, ut rhoncus risus ultricies vitae. Morbi ac ex eget neque feugiat auctor.\r\n\r\nAliquam ac dui vel metus tincidunt suscipit. Praesent interdum diam at lorem sodales, ut sodales quam volutpat. Etiam suscipit nibh justo. Ut rhoncus nec tellus eu ornare. Aenean congue eget sapien a malesuada. Etiam ante ipsum, efficitur id lorem nec, varius gravida enim. Mauris mauris orci, efficitur finibus iaculis et, consequat quis urna. Pellentesque vitae tristique diam. Vivamus tincidunt rutrum massa. Aenean magna lectus, cursus eget viverra eget, placerat pellentesque ipsum. Maecenas et ornare augue. Sed ut placerat urna, nec laoreet purus. Fusce cursus iaculis enim, nec finibus lacus imperdiet vitae. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin iaculis sit amet urna non lacinia.\r\n\r\nAenean ultricies tellus nec tortor vulputate, ac sagittis nibh auctor. Etiam suscipit tempus hendrerit. Integer tincidunt malesuada convallis. Proin eu pellentesque ligula, quis pharetra lectus. Vivamus vehicula pellentesque leo. Vivamus sed aliquet elit, nec elementum metus. Aenean eu ipsum fringilla, accumsan dui sed, lobortis risus. Etiam et semper justo. In at est ac risus varius fringilla. Quisque nec dolor odio. Pellentesque eget dui lorem.\r\n\r\nIn ornare fermentum mi, ac auctor sapien mattis eget. Aliquam laoreet porttitor enim non scelerisque. Proin eu dolor in magna luctus blandit at eu tellus. Cras eu semper mi, sed fringilla urna. Etiam finibus turpis euismod, vehicula leo sed, suscipit elit. Etiam ut facilisis dui, nec fermentum erat. Nulla facilisi. Nam luctus ligula non dolor pulvinar, quis fermentum libero porttitor.\r\n\r\nMauris diam urna, lacinia quis massa fringilla, sagittis tincidunt turpis. Phasellus non diam orci. Proin augue tortor, varius sed ultricies non, sodales in dolor. Phasellus in volutpat purus. Vestibulum non tortor placerat, interdum orci ut, ultrices nunc. Maecenas facilisis diam enim, quis laoreet nisl viverra non. Proin ac libero mollis, tempor nulla sit amet, rutrum ligula. Donec accumsan dictum nunc et congue. Suspendisse eget suscipit metus, sagittis rhoncus dui. Ut luctus, turpis vitae convallis placerat, ligula quam posuere enim, id condimentum nisi nibh nec augue. Pellentesque a augue euismod, egestas lacus eget, egestas nibh. Donec consectetur, ligula tempor facilisis hendrerit, ipsum erat dignissim lacus, non posuere massa sem in turpis. Mauris in pretium velit, at finibus leo. Quisque mauris tortor, tempor laoreet tempus vel, interdum vel arcu. Praesent ante purus, tincidunt nec urna nec, ullamcorper fringilla massa.\r\n\r\nEtiam eleifend ex at orci egestas tincidunt. Praesent nec luctus nulla, vitae elementum urna. Integer pellentesque est in est porta cursus. Phasellus gravida, est eget ullamcorper sollicitudin, erat ante molestie sem, eu vehicula erat dui nec magna. Phasellus neque nibh, hendrerit nec libero eget, finibus pellentesque massa. In ultricies rutrum diam eu porttitor. Sed quis massa convallis, molestie erat non, porttitor odio. Proin dui nibh, auctor eu diam vitae, convallis feugiat eros. Aenean semper a risus ut dapibus. Aliquam aliquam ut lacus a mattis. In sed elit nisi. Curabitur eu luctus purus. Integer magna odio, tempus et mattis bibendum, sodales in nisl.\r\n\r\nVestibulum convallis est sed consequat tincidunt. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean sed justo volutpat, iaculis leo id, porta tellus. Proin sollicitudin at orci eget lobortis. Vestibulum lorem sem, placerat at sodales a, bibendum non erat. Aliquam finibus suscipit finibus. Aliquam rhoncus metus in mattis cursus. Pellentesque ut elit varius, cursus lacus sit amet, fermentum arcu. Phasellus posuere sed justo non tincidunt. Duis facilisis purus id aliquam vehicula. Cras a sapien quis justo posuere tempus. Mauris scelerisque orci ligula, sit amet ornare nunc dignissim ut. Pellentesque varius nulla malesuada consectetur porttitor. Integer nec lorem sed eros commodo vulputate. Nunc massa mi, dapibus semper nisi vel, consequat posuere arcu.\r\n\r\nInteger arcu nibh, rutrum aliquet neque sed, laoreet fringilla nulla. Sed luctus augue est, sit amet consectetur lorem convallis a. Proin eu elit eu est vulputate finibus. Vestibulum molestie nunc purus, eu consequat magna euismod at. Donec luctus ipsum et aliquet finibus. Nulla lacinia mattis ante vel consequat. Suspendisse ac risus nunc. Praesent sed turpis a magna tempus facilisis a vel nulla. Nulla ac nunc id tortor sagittis tempus fringilla a velit. Aliquam laoreet, sapien quis tempus sagittis, felis massa maximus ante, ut lobortis libero erat id est. Cras ultricies facilisis libero, non vulputate nisl elementum quis. Nunc imperdiet consequat luctus. In volutpat ante felis, eu scelerisque felis vulputate non. Maecenas sed turpis sed metus consequat commodo a vitae ex. Nullam vehicula sem eget sapien eleifend, ut pharetra leo laoreet. Praesent eu lectus ac nisi aliquam consequat.\r\n\r\nDonec vel augue at lorem dapibus tempor. Vestibulum in turpis ac urna faucibus sodales. Mauris neque sapien, placerat vitae maximus quis, semper sit amet mi. Mauris in sem a libero cursus cursus ut eu sapien. Nam vehicula et metus at consequat. Pellentesque at rutrum velit. Nulla semper leo nisl.\r\n\r\nDonec pharetra porta rutrum. Donec ultricies erat et purus semper, vitae bibendum enim consequat. Sed sodales orci eros. Cras quis eros et purus venenatis mollis at et ipsum. Donec tempus dui vitae egestas euismod. Pellentesque lacus velit, ullamcorper finibus lacinia nec, semper eu ante. Nullam imperdiet, orci placerat efficitur placerat, urna libero ornare elit, at ullamcorper nisl lectus in nisi. Nunc ac urna augue. Integer id augue felis.\r\n\r\nDonec nec magna quis est sagittis semper nec non nisl. In hendrerit, nulla non tristique blandit, mauris purus rutrum enim, vel efficitur lectus eros non urna. Phasellus orci sem, blandit ac pretium eu, lobortis quis tortor. Donec diam dui, fringilla sed pellentesque ac, interdum et justo. Etiam pretium facilisis tempus. Fusce auctor auctor malesuada. Cras suscipit mi sed ante viverra iaculis. Vivamus enim risus, maximus vitae risus eu, aliquet tincidunt nulla. Praesent ac nisi condimentum nunc maximus hendrerit. Proin interdum sodales purus. Mauris rutrum velit et mattis consequat.\r\n\r\nSuspendisse eget aliquet erat. Phasellus molestie nunc risus, non maximus ligula placerat vitae. Interdum et malesuada fames ac ante ipsum primis in faucibus. Cras aliquam maximus elit, ut aliquam ante. Sed ut mauris sit amet eros semper posuere. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Fusce justo lorem, ornare sed egestas sit amet, sagittis sed ex. In hac habitasse platea dictumst. Nullam odio risus, suscipit in laoreet vitae, malesuada nec felis. Morbi luctus sodales nibh, accumsan pulvinar risus finibus sed. In sodales metus id urna dictum, fermentum facilisis ex dapibus.\r\n\r\nUt venenatis rutrum condimentum. Vestibulum eget vehicula augue. Proin maximus tempor dui, vel viverra odio convallis ut. Etiam interdum, ipsum id molestie mattis, mauris ligula molestie erat, iaculis scelerisque sem sapien ac metus. Nullam id tincidunt lacus, vel auctor augue. Proin id leo nec metus semper ullamcorper in non ligula. Nam vestibulum rutrum turpis, sollicitudin suscipit tortor vehicula nec.\r\n\r\nVivamus sodales neque et elit aliquam sagittis. Integer nisi lectus, hendrerit quis tempus accumsan, facilisis vel sem. Donec ullamcorper nunc fringilla ultrices auctor. Etiam pharetra bibendum euismod. Nulla feugiat feugiat felis vitae porta. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vel egestas purus. Nunc bibendum turpis ut tellus vehicula consectetur. Pellentesque dignissim egestas consequat. Ut molestie quam ac orci auctor dapibus. Nulla eu tristique metus, id laoreet libero. Proin vel diam eu enim rhoncus lobortis. Aliquam rutrum dictum dui, sit amet mattis dolor euismod ac. Vivamus facilisis dolor ac maximus tincidunt. Morbi urna urna, bibendum in consectetur nec, posuere tincidunt nisl.\r\n\r\nDuis vitae massa sapien. Pellentesque quis porta nibh. Suspendisse sit amet purus tincidunt, sollicitudin magna at, sollicitudin orci. Phasellus enim felis, molestie vel finibus quis, interdum eu nisi. Cras elementum quam vel congue interdum. Nunc nec scelerisque dolor. Maecenas eu consectetur nisi. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum volutpat libero vel ante porttitor, ut tempus purus mattis. Cras non diam lobortis dolor bibendum pulvinar at vel arcu. Nam interdum magna at eros pharetra venenatis. Nunc vitae mauris et sem iaculis egestas eu eu orci. Quisque pretium tortor ipsum, mollis volutpat velit vestibulum pulvinar. Sed porttitor vulputate ligula ut mollis. Vivamus lacinia nibh justo, lobortis dignissim sapien ultricies non. Donec sit amet tempus urna, et iaculis purus.\r\n\r\nAliquam erat volutpat. Nunc vitae malesuada turpis. Vivamus quis felis sollicitudin, pellentesque leo ac, placerat ante. Fusce aliquam dolor at luctus aliquam. Phasellus posuere pharetra enim, a finibus lorem dignissim ornare. Donec tortor libero, molestie vel purus luctus, viverra tincidunt nibh. Ut imperdiet fermentum ornare. Vivamus pretium pharetra rutrum. Morbi quis ante imperdiet, tincidunt metus consequat, ultricies nunc. Quisque scelerisque dictum felis ac mollis. Fusce sit amet mi mi. Sed in bibendum neque, vel euismod orci. Nam cursus lobortis massa. Vivamus sagittis quam dui, hendrerit lacinia quam vulputate ac.\r\n\r\nPraesent semper nunc sit amet varius lacinia. In sodales enim et nisi imperdiet, eget varius metus sagittis. Sed nec nibh quam. Nunc mattis justo vitae velit tempor facilisis non sit amet leo. Donec vitae elementum nisi. Suspendisse sed sapien id ligula egestas porttitor. Phasellus at pellentesque velit. Sed nec ex quis nibh scelerisque pulvinar. Curabitur ut eros ut erat semper volutpat. Fusce interdum lectus a ex venenatis, et pellentesque sapien dignissim.\r\n\r\nFusce eget tincidunt urna. Cras eros urna, commodo nec nibh nec, scelerisque tincidunt lorem. Nam vel consectetur massa. Mauris diam est, porttitor non pharetra nec, tincidunt non magna. Fusce et leo diam. Nullam leo arcu, cursus et neque at, tincidunt laoreet lorem. Nunc euismod ullamcorper urna sed laoreet. Praesent condimentum ipsum a dui viverra vulputate. Maecenas sollicitudin ac orci pellentesque viverra. Maecenas non blandit ligula. Mauris pellentesque viverra feugiat. Ut quis gravida diam.\r\n\r\nNunc ac lobortis tellus. Praesent tellus ex, imperdiet at feugiat sed, rutrum at nulla. Donec sit amet urna cursus, luctus dolor ac, blandit purus. Sed interdum, metus ac placerat varius, eros justo placerat felis, tristique sodales erat risus nec lorem. Etiam dictum aliquet velit, at facilisis diam facilisis a. Etiam vel interdum sapien, id mattis purus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus suscipit quis metus auctor porttitor.\r\n\r\nQuisque commodo diam cursus, sollicitudin ante sit amet, lacinia enim. Nam scelerisque tempus aliquet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed ut nulla magna. Phasellus convallis pharetra auctor. In ornare neque enim, sit amet interdum nulla ultrices id. Ut sit amet ornare risus. Aliquam erat volutpat. Maecenas mattis sapien luctus lacus ullamcorper, vel lobortis leo commodo. Suspendisse sit amet scelerisque turpis. In nisl leo, pharetra sodales gravida nec, faucibus ut odio. Quisque quis lectus faucibus, dapibus ligula vulputate, euismod felis. Nam at lectus ac metus commodo lacinia nec sed metus. Integer turpis ante, venenatis a fringilla ac, pellentesque ac lectus. Vivamus enim lectus, luctus id laoreet in, sodales vitae turpis. Pellentesque nulla nisl, tincidunt et leo vel, condimentum interdum sem.\r\n\r\nNullam fringilla lectus quam, vel malesuada ex feugiat quis. Fusce elementum imperdiet bibendum. Aenean dictum viverra tellus vitae dignissim. Vestibulum vitae risus ac felis viverra ultrices. Aenean accumsan condimentum viverra. Donec fermentum vulputate blandit. Nunc non orci orci. Suspendisse pulvinar metus in nisl convallis, sed convallis felis rhoncus. In varius pretium tincidunt. In sit amet mauris nec diam sollicitudin venenatis vitae sit amet ante. Nam aliquet placerat magna a vestibulum. Nunc velit mi, tempus et magna ut, commodo pulvinar tellus.\r\n\r\nVivamus vehicula nec libero vitae dapibus. Nulla consequat vehicula lectus, ut venenatis ipsum gravida et. Sed rhoncus, est eu viverra dignissim, urna neque feugiat lorem, nec euismod ex nisi eget libero. Nulla facilisi. Mauris ornare, purus et dapibus placerat, odio augue pharetra risus, in finibus arcu justo nec tortor. Duis commodo tellus mollis tincidunt malesuada. Proin accumsan mauris vel magna aliquet ultricies. In eget leo in enim vehicula vehicula at ut nisl. Sed sodales, lectus posuere porttitor condimentum, massa sem mattis nisl, quis interdum nisi ligula vel magna. Nam mauris velit, euismod eget bibendum placerat, interdum ac mi. Quisque posuere lobortis lorem, sed sollicitudin eros feugiat congue. Nam in tempor magna, vel gravida turpis. Morbi eget rutrum elit, sit amet ultricies erat. Nunc ornare velit sed lacus scelerisque convallis. Proin pretium quis ex et vehicula.\r\n\r\nMorbi dapibus gravida arcu, ac tincidunt orci pulvinar eu. Integer id urna et magna placerat faucibus eget non enim. Morbi ipsum libero, volutpat quis erat non, euismod lobortis ex. Pellentesque ut sem a tellus rutrum pretium sed et erat. Donec vitae hendrerit elit. Sed volutpat elit hendrerit, condimentum dui a, molestie enim. Morbi arcu orci, pulvinar vel urna sit amet, dapibus tempor mi. Proin accumsan dictum leo. Phasellus ante purus, tristique et pulvinar id, aliquam et augue. Ut dapibus, lectus vulputate dignissim eleifend, turpis leo ultricies dolor, quis pellentesque arcu nulla a felis. Nulla vehicula, purus eu fringilla convallis, neque dui molestie metus, sed dictum urna dolor a nisl. Ut molestie eros quam, eget tincidunt sem luctus non.\r\n\r\nMorbi mollis blandit nibh, in sodales magna finibus tempor. Proin pharetra accumsan consectetur. Proin consectetur venenatis eros. Morbi lorem tellus, laoreet sit amet purus et, consequat convallis risus. Mauris et sagittis ante. Vivamus sed est sed felis congue molestie. Maecenas blandit nisi a tristique sollicitudin. Quisque in venenatis libero, vitae rutrum ipsum. Fusce massa sapien, euismod ornare felis a, lacinia ultricies nisi. Maecenas ac diam aliquet diam facilisis gravida a et purus. Proin id pretium elit. Cras cursus tortor ipsum, vel rhoncus arcu volutpat a. Suspendisse elementum efficitur lacus, eget finibus urna rhoncus non. Etiam mollis eros accumsan felis eleifend, id interdum nisl interdum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.\r\n\r\nUt ultrices lacus sit amet aliquet tempor. Proin viverra, risus nec pellentesque consequat, risus nisi tincidunt nibh, id ultricies urna turpis quis metus. Vestibulum sit amet orci pellentesque, vulputate massa vel, tempor orci. Etiam massa magna, condimentum et nulla eu, blandit posuere ligula. Nunc venenatis eros ac sapien pulvinar tempus in sit amet augue. Suspendisse sollicitudin mollis urna, quis dictum purus tincidunt in. Proin sollicitudin libero eget nisi blandit, id dictum nisi aliquet. Cras et dictum neque. Nunc eu luctus massa. Ut posuere dapibus enim dictum scelerisque. Donec sapien sem, tempus lacinia metus eu, blandit finibus urna. Phasellus dignissim augue a turpis tristique malesuada. Sed vehicula tristique velit. Fusce vel mi lacus. Aenean dapibus sollicitudin congue.\r\n\r\nVestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nulla neque sem, varius in sapien in, iaculis pretium purus. Vestibulum convallis elit sit amet magna fermentum semper. Nulla varius arcu vel volutpat sagittis. Suspendisse pulvinar sapien at vehicula placerat. Nullam in mattis lectus. Sed in eros quis odio fringilla fermentum sed nec velit. Praesent condimentum interdum imperdiet. Integer justo arcu, dapibus vitae bibendum aliquam, eleifend id turpis. Etiam pretium vitae dolor sit amet ultrices. Duis urna mi, accumsan et auctor vitae, dapibus et lorem. Nulla quam leo, tempus eget ante sed, imperdiet dapibus nunc. Integer viverra luctus ligula, sed tempor orci volutpat ut. Nullam a libero vel neque sagittis lobortis. Praesent semper est non dolor suscipit aliquet. Proin posuere aliquet urna quis ullamcorper.\r\n\r\nPhasellus lobortis lobortis feugiat. Donec in felis ut neque mattis finibus. Aenean ac pellentesque risus. In hac habitasse platea dictumst. In dapibus interdum ligula ac posuere. Integer non nunc pharetra, ultricies diam vitae, posuere urna. Fusce vulputate sapien eu venenatis ornare.\r\n\r\nMauris fringilla leo sed augue posuere, vel commodo tellus interdum. Nunc elit elit, posuere et ante vitae, vulputate imperdiet augue. Curabitur mattis mollis nulla, a venenatis massa sollicitudin sit amet. Suspendisse lacus urna, tempor ut enim a, pulvinar dapibus arcu. Sed ut est consequat, dictum lacus ut, laoreet felis. Ut et sem ac sem tempus cursus et in urna. Vestibulum metus sapien, convallis vitae elementum vulputate, interdum et dui. Ut ornare vitae risus sit amet tincidunt. Curabitur eget tempor mi, vel aliquam arcu. Sed eu ligula pellentesque, euismod tortor et, maximus sem.\r\n\r\nSed condimentum metus vel orci volutpat, non cursus ipsum vestibulum. Nulla facilisi. Cras ut ultrices ex, ac mattis mi. Ut ac egestas justo. Nullam at sem auctor, fermentum metus at, dictum purus. Nam sit amet blandit quam. Proin facilisis, tellus id rhoncus feugiat, massa ex volutpat purus, in rutrum sapien libero quis orci. Vestibulum rutrum suscipit feugiat.\r\n\r\nMorbi aliquet feugiat ultricies. Donec ut nisi leo. Phasellus nec rhoncus dolor. Pellentesque eu tincidunt elit. Fusce convallis neque non lacus consectetur vulputate. Aliquam a facilisis leo, laoreet sodales orci. Nulla elementum leo eu diam pellentesque volutpat. Suspendisse efficitur blandit felis, feugiat mollis odio hendrerit egestas. Cras venenatis mollis tortor eu condimentum. Aliquam ullamcorper porttitor felis eget maximus. Aliquam et pellentesque lectus.\r\n\r\nNunc egestas facilisis augue, sed efficitur nisi mollis nec. Cras aliquam posuere risus, sed venenatis nunc aliquam vel. Nunc pellentesque commodo velit, sit amet maximus mauris egestas ac. Donec faucibus id mi ac vulputate. Phasellus vitae ipsum pharetra risus aliquet consectetur id ut nisl. Proin imperdiet neque dui. Duis purus lorem, gravida nec luctus nec, fermentum a odio. Nullam eget magna id elit porttitor blandit mattis ac tortor. Integer molestie convallis tempus. Cras quis ullamcorper sem.\r\n\r\nUt fermentum mollis venenatis. Nunc sed suscipit risus. Phasellus velit leo, vehicula sed massa vitae, facilisis luctus dolor. Mauris id bibendum sapien, at porta tortor. Fusce elementum ut nunc ac pharetra. Praesent vehicula lorem sed mi euismod semper. In eros enim, mollis a posuere ut, feugiat id est.\r\n\r\nVivamus commodo, nisi ut sodales interdum, massa nibh efficitur mi, vitae consectetur diam leo sed dui. Nam a commodo tellus, vel consequat odio. Donec laoreet rutrum dui, ac eleifend felis volutpat vitae. Pellentesque at tincidunt lectus, sed scelerisque nisi. Vestibulum feugiat felis fermentum risus consectetur dignissim varius sit amet mauris. Etiam orci sapien, tincidunt id pharetra at, vulputate at metus. Aenean semper imperdiet ligula, et hendrerit dolor rutrum eget. Phasellus bibendum augue eget sem venenatis scelerisque. Quisque justo dolor, lacinia a cursus quis, ultricies luctus augue. Praesent gravida lacus vitae eros varius mattis. Suspendisse in metus enim. Vestibulum sit amet lorem ultricies, vulputate odio ac, ullamcorper augue.\r\n\r\nVivamus faucibus lorem auctor tincidunt semper. Pellentesque efficitur suscipit dapibus. Nunc ullamcorper non tellus nec vulputate. Maecenas quis tortor condimentum, ornare ligula sed, lobortis nunc. Sed sagittis elit eu porta efficitur. Cras vel arcu tempor, mollis dui quis, volutpat orci. Etiam molestie, ipsum et placerat ullamcorper, elit risus ultricies magna, sed feugiat velit leo nec erat. Maecenas nisl risus, accumsan quis velit in, facilisis consequat lacus. Donec nec risus ligula. Praesent ex augue, imperdiet id est eu, facilisis finibus mi. Nulla facilisi.\r\n\r\nDonec malesuada sem orci, at pulvinar ex gravida et. Nunc tellus turpis, tempus aliquam tincidunt scelerisque, pharetra vel massa. Proin non lacus posuere, tincidunt turpis et, sodales eros. Proin tincidunt non turpis ut hendrerit. Vivamus varius placerat sem in porttitor. Quisque porttitor purus augue, sit amet cursus quam convallis a. In a arcu non odio pulvinar accumsan vitae vel massa. Praesent quam elit, tempus quis venenatis eu, sodales et orci. Sed eros ligula, consectetur vitae laoreet ultricies, mattis quis nisl. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed eget sapien porta, aliquet nunc eget, accumsan eros. Etiam volutpat congue porta. Sed sapien metus, viverra ut egestas non, dignissim ut velit. Integer rhoncus lectus nec nunc posuere, a aliquet diam tristique. Praesent volutpat lobortis sapien nec iaculis. Nulla et orci pulvinar, malesuada turpis quis, ullamcorper dolor.\r\n\r\nMaecenas semper lorem in congue tristique. Sed rhoncus vel purus sed mollis. Nunc nec ligula a ex interdum porta. Fusce placerat nunc in turpis posuere iaculis. Fusce mollis lectus nec ullamcorper lacinia. In tincidunt ex id viverra sollicitudin. Morbi volutpat a dolor eu aliquet. Nam ut volutpat libero, a maximus velit. Suspendisse maximus lorem eget lectus convallis facilisis. Mauris convallis posuere ullamcorper. Aliquam nec urna nec odio posuere malesuada. Fusce et est dictum, commodo tortor vel, sodales ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r\n\r\nDonec consectetur porta efficitur. Suspendisse at nunc lectus. Donec ut leo a purus fringilla gravida. Aliquam scelerisque et ante eget luctus. Vivamus in nisl nec quam mollis sodales. Proin id malesuada dolor, quis convallis purus. Donec tincidunt fermentum erat at bibendum. Vivamus aliquam nisl ut vestibulum cursus. Aenean a fringilla nisi. Nam blandit iaculis faucibus.\r\n\r\nIn hendrerit elit vitae orci dignissim lobortis. Nulla facilisi. Fusce et turpis quis metus varius interdum. Cras imperdiet rutrum orci, quis blandit mi. Phasellus at vehicula dui, in fermentum nulla. Nunc imperdiet quis diam eu molestie. Etiam gravida et risus vitae sodales. Donec et vehicula magna. Vestibulum non tellus pretium, elementum felis a, vestibulum augue. Suspendisse potenti. Duis lacinia purus non mauris finibus, a pellentesque est pharetra. Praesent tincidunt rhoncus eros. Phasellus laoreet, est quis condimentum congue, mi odio lobortis odio, et sagittis massa est non lacus. Donec elementum mauris felis, ut cursus ante interdum vel.\r\n\r\nNullam vitae tortor interdum purus fermentum tempor. Aliquam cursus sed dui et semper. Suspendisse finibus, velit sit amet pharetra gravida, felis erat tempor odio, vel volutpat lorem nisl eget mi. In volutpat, lorem at aliquet faucibus, augue eros faucibus metus, a ultrices sapien orci vel ipsum. Aliquam nec ornare lectus, eu tincidunt est. Ut vitae sem dui. Fusce et elementum risus, ut tincidunt elit. Proin elementum gravida mattis. Aliquam malesuada pharetra venenatis. Aliquam eget venenatis orci, quis lobortis lacus. In interdum velit id metus commodo, eu venenatis lorem molestie.\r\n\r\nMauris pretium dolor enim, a tempus sapien dignissim id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut volutpat neque felis, cursus imperdiet sapien commodo sit amet. Integer rutrum ac erat eget malesuada. Vivamus mattis ante sed elit gravida tincidunt. Cras vel ex tempor, porta nunc in, facilisis lectus. Nulla in viverra justo. Suspendisse blandit lobortis orci, vitae luctus urna placerat sed. Nullam at massa nec quam facilisis eleifend.\r\n\r\nFusce libero quam, maximus vel pretium et, eleifend sit amet nulla. Aliquam erat volutpat. Nam aliquam ligula tellus, vitae posuere ligula dictum vitae. Sed velit ante, fringilla eget lacus ut, maximus vestibulum felis. Vivamus dui risus, iaculis sed feugiat a, maximus vitae augue. Nulla non augue ut velit eleifend fringilla. Nullam non aliquet magna, convallis tincidunt ipsum. Mauris sit amet vulputate ante, sed euismod erat. Donec sed ex vulputate, condimentum turpis non, pellentesque lectus. Cras diam turpis, sollicitudin et posuere a, viverra vitae velit. Maecenas vestibulum ligula sit amet scelerisque sodales. Duis et nibh vitae nisl tempor vehicula vel a nibh. Donec dapibus tellus eu arcu dictum porttitor. Nulla tincidunt eros quis ex blandit finibus. Nulla eget commodo velit.\r\n\r\nMaecenas convallis a erat eget gravida. Nulla ac sodales lorem, id aliquet ex. Pellentesque feugiat volutpat lectus vitae vulputate. Phasellus venenatis placerat porta. Phasellus nec ultricies ipsum. Nam faucibus lectus et lacus vestibulum scelerisque. Sed condimentum risus in enim venenatis, non iaculis risus aliquet. Maecenas vestibulum nisl in elit lobortis, sit amet sagittis magna facilisis. In dictum felis vel tortor dictum, eget consectetur purus feugiat. Etiam venenatis justo orci, at mattis dolor pretium id. Suspendisse quis porta ante. Sed sit amet arcu sodales dui mattis iaculis vitae sed sapien. In neque elit, bibendum quis maximus nec, imperdiet at mauris. Aliquam pulvinar fringilla egestas. Aenean ornare nulla non felis auctor, a placerat odio accumsan.\r\n\r\nPraesent consequat tempor pretium. Aliquam dignissim porttitor mi, sit amet mollis ipsum iaculis in. Nullam tincidunt fringilla sagittis. Donec dolor diam, eleifend et eros quis, semper vehicula tellus. Aenean sit amet augue est. Aenean nulla neque, commodo ac erat vel, laoreet sodales arcu. Nullam mollis lorem elit, nec mollis ex sagittis ut. In suscipit, metus a accumsan egestas, urna ante faucibus neque, id tincidunt eros quam vitae magna. Donec pharetra scelerisque nulla, tempor pretium erat gravida nec. In id sapien ex. Suspendisse augue sem, convallis eget blandit in, congue ac mauris. Vestibulum quam erat, dignissim vehicula iaculis nec, fringilla et tortor.\r\n\r\nNullam ac mauris ultricies, facilisis leo a, dictum libero. Duis vitae feugiat massa, ac sodales urna. Nullam non dapibus risus. Aliquam erat volutpat. Quisque ipsum elit, iaculis eu nunc a, euismod porta diam. Curabitur ultricies ante et arcu laoreet, vel porttitor tortor finibus. Suspendisse sem leo, rutrum ut tincidunt in, fermentum sit amet erat. Fusce elementum lobortis neque, sed tempor lorem. Suspendisse potenti. Nunc vitae tortor aliquam, dignissim enim vel, ultrices sapien. Duis in bibendum sem.\r\n\r\nAenean venenatis euismod arcu, nec ultricies eros laoreet et. Integer a sapien blandit mauris cursus eleifend sed vitae neque. Sed elementum arcu lacus. Mauris eget tincidunt mauris. Cras cursus nisi eu ligula aliquet suscipit. Donec hendrerit commodo tempus. Vivamus lacinia mattis scelerisque. Suspendisse facilisis molestie lorem tincidunt mattis. Sed tellus mi, posuere nec mauris ut, aliquet dignissim neque. Donec pharetra auctor ultricies. Nunc nec turpis tincidunt, lobortis enim sed, gravida turpis. Nullam auctor magna sit amet ligula luctus posuere vitae eget justo. Phasellus finibus eros suscipit sem facilisis, venenatis dignissim massa dignissim. Aliquam ut aliquet lorem.\r\n\r\nInteger et ex dignissim, aliquam purus ac, bibendum ex. Vestibulum quis dolor id est auctor blandit. Nunc non aliquet tellus. Phasellus fringilla nec est eu tempor. Morbi id ipsum at nunc mollis iaculis. Integer viverra sem justo, vitae feugiat arcu euismod id. Donec sagittis nunc et ligula cursus, vitae convallis dui gravida.\r\n\r\nSed ullamcorper tortor vitae purus ultricies, ac vehicula mi auctor. Vestibulum maximus, magna consequat convallis tempor, dui elit fringilla ligula, ut porta ligula elit non odio. Proin convallis orci quis sapien commodo, eu ultricies sapien ultricies. Nullam pharetra libero a ante eleifend, sit amet iaculis odio congue. Duis in neque sed turpis posuere porta at a orci. Praesent dapibus rutrum nisi, a vestibulum mi finibus vitae. Phasellus sollicitudin justo nec posuere porttitor. Donec eu eros dictum, pharetra diam a, iaculis massa. Aliquam risus turpis, maximus dapibus interdum vel, hendrerit et nisl. Curabitur ante elit, congue at nibh sed, cursus sagittis nulla. Pellentesque maximus malesuada massa, vel feugiat arcu consequat ut. Nam tristique diam eu eros sagittis, ac placerat diam laoreet.\r\n\r\nDonec iaculis non massa eget luctus. Nulla semper molestie lacus, et vulputate justo convallis eu. Morbi vitae lectus id enim ultrices pretium. Quisque porttitor, nibh vel fringilla facilisis, nisi eros ultrices leo, sed bibendum nunc risus vitae odio. Phasellus id justo elementum, fermentum augue ac, convallis elit. Nulla vehicula arcu ut tellus iaculis, a mollis augue finibus. Duis nec justo bibendum, fermentum felis in, porta mi. Integer tempus mauris in ligula mollis euismod. Aenean urna turpis, laoreet in ex nec, gravida sollicitudin ipsum. Nulla egestas massa in velit tempor fringilla. Nam posuere, ipsum ac volutpat congue, sapien elit pharetra nisl, quis commodo ligula erat vitae tortor. Nunc accumsan lobortis neque eu viverra. Nunc cursus fermentum tincidunt. Pellentesque eget maximus lorem. Quisque accumsan iaculis dolor, in scelerisque augue dictum quis.\r\n\r\nInteger dignissim mauris eu diam fermentum fermentum. Mauris in ex ut dui bibendum ultricies et eu justo. Aenean vitae velit quis dui dictum pulvinar vitae non massa. Proin rutrum posuere est ac egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tincidunt dui porta, efficitur mauris sed, vestibulum felis. Aliquam ante justo, volutpat quis nunc facilisis, vulputate sagittis diam. Nunc maximus, metus id facilisis consectetur, turpis nisl cursus diam, maximus feugiat eros odio vitae velit.\r\n\r\nAliquam scelerisque ornare ligula vel venenatis. Maecenas auctor nisi eget erat rutrum, tincidunt iaculis dui dictum. Morbi malesuada lorem luctus, scelerisque sem vel, egestas massa. Sed mi nibh, dignissim et odio ut, vulputate aliquet diam. Aliquam venenatis tellus in felis auctor consectetur. Proin ornare nunc vitae nisl bibendum, sit amet auctor ex eleifend. Nulla eu mi risus. Praesent et finibus dui.\r\n\r\nMauris porta condimentum fermentum. Fusce efficitur diam a tempus laoreet. Nunc odio erat, tristique id semper id, porta at nulla. Aliquam erat volutpat. Morbi varius vestibulum fringilla. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam mattis massa urna, nec egestas massa gravida vitae. Quisque finibus sapien id lorem bibendum, vitae ultrices dolor euismod. Curabitur pellentesque posuere dictum. Curabitur ultricies sapien libero, ut tempus lorem ullamcorper molestie. Maecenas in turpis vitae eros blandit posuere. Integer sollicitudin odio urna. Integer varius nibh augue, id accumsan leo semper ac. Vestibulum diam risus, vulputate ac sapien sit amet, pulvinar elementum felis.\r\n\r\nEtiam quis felis justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dui ante, faucibus eget mattis non, lobortis vel lacus. Phasellus sit amet justo id mauris suscipit dictum. Maecenas in tortor interdum, semper lacus vel, dapibus nibh. Maecenas sit amet urna sapien. Ut eget leo ligula. Sed quis dignissim augue, vitae vestibulum tellus.\r\n\r\nDonec pharetra risus non lorem hendrerit, sit amet suscipit nisi sodales. Ut a turpis enim. Nunc ut ante sit amet urna rutrum eleifend vitae a justo. Sed rutrum id urna ac efficitur. Ut a dui dui. Donec molestie eu felis quis dictum. Proin consectetur eu nibh mattis consectetur. Vivamus molestie libero ut dui fringilla, vel luctus elit porta. Aliquam eget vulputate libero, at placerat lacus. Etiam dapibus pulvinar purus at ultricies. Integer ut efficitur dui, in lobortis nunc. Aenean laoreet rhoncus arcu eget sagittis. Fusce malesuada maximus est eu dictum. Vestibulum vitae enim magna.\r\n\r\nIn hac habitasse platea dictumst. Sed tempus dictum ipsum. Quisque volutpat tortor nec velit congue condimentum. Mauris sagittis ultrices ante, et laoreet mauris cursus nec. Nam suscipit ornare tempor. Cras ante nisl, pretium ac lacus in, sodales feugiat nunc. Vivamus fermentum erat eget nunc placerat faucibus. Mauris leo risus, feugiat dapibus gravida sit amet, dignissim eu sapien. Nulla nec commodo nisi. Donec nec ante at nisi fermentum scelerisque. Duis non consequat elit. Vivamus sit amet orci bibendum, faucibus purus eu, commodo mauris.\r\n\r\nSed eget augue fringilla, convallis eros ut, egestas velit. Ut semper dui et enim maximus, vitae lacinia turpis commodo. Cras vitae sem mauris. Mauris dapibus ante facilisis facilisis placerat. Sed nec ex at nunc euismod rhoncus at sed purus. Nam luctus hendrerit sapien, sit amet pulvinar nunc venenatis id. Donec rhoncus, sem et vestibulum interdum, ante nisl posuere diam, non tempor justo mi vel diam. Aliquam ultrices, nulla nec blandit tincidunt, felis lacus rutrum sapien, posuere accumsan libero magna non odio. Praesent vel enim pharetra, ultricies lacus aliquet, volutpat arcu.\r\n\r\nMaecenas ut elementum purus, sit amet tincidunt augue. Nam mauris magna, convallis sed nibh ut, pharetra scelerisque nisl. Aliquam consectetur mi vel erat ultrices, ut accumsan sem varius. Nulla sit amet nulla et arcu sodales dignissim eget in sapien. Duis maximus in metus ut vestibulum. Curabitur id consequat tellus, nec molestie erat. Morbi quis urna sit amet diam varius ultrices ut vitae elit. Vivamus iaculis imperdiet nulla, eu ornare augue pulvinar ac. Integer iaculis ipsum ut nisi porta, in mollis ipsum volutpat. Fusce rhoncus consectetur sodales. Pellentesque gravida nunc odio, scelerisque pellentesque augue accumsan id. Mauris sollicitudin at urna id consectetur.\r\n\r\nNullam turpis dui, feugiat et ante at, fringilla molestie leo. Curabitur eget vehicula augue, id dapibus nulla. Integer sed ex sit amet lacus viverra tincidunt imperdiet at diam. Maecenas pharetra ullamcorper nisi, quis finibus leo faucibus et. Nam accumsan placerat eros id commodo. Nulla tempor lacinia mi, eu aliquet leo. Ut ut vestibulum nunc. Vivamus pellentesque porta magna a porta. Etiam urna odio, mollis nec erat eget, elementum auctor dui. Aliquam sagittis vulputate sagittis.\r\n\r\nUt mattis interdum euismod. Etiam quis purus ut lorem placerat luctus. Praesent libero velit, facilisis non nisl et, elementum porta massa. Ut in odio vel lacus luctus gravida. Suspendisse vitae dolor mi. Nam eu ante ac purus faucibus pulvinar. Phasellus eu euismod felis, non malesuada magna.\r\n\r\nDonec sed est et nulla aliquam pretium. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent ac vehicula mauris, vitae cursus neque. Donec laoreet tincidunt libero, nec vulputate sapien porta sit amet. Proin sit amet lorem eu augue auctor rhoncus nec quis mi. Ut volutpat placerat dolor, in vulputate mauris pellentesque vitae. Aenean elementum consequat felis in euismod. Morbi commodo sapien vitae nunc sodales blandit. Vivamus nec elit libero.\r\n\r\nMorbi sit amet varius tellus. Etiam tellus elit, sollicitudin nec feugiat non, venenatis quis lectus. Pellentesque mattis lacus at iaculis gravida. Curabitur porta id erat nec ullamcorper. Etiam feugiat, nisl in malesuada gravida, mi quam mattis nunc, eget ultricies risus dolor eget tortor. Pellentesque finibus lacinia sapien, in sollicitudin orci dapibus at. Suspendisse dictum nec sapien ut gravida.\r\n\r\nPellentesque tincidunt, nisl id pretium hendrerit, ligula sem tempor quam, eget lacinia sem sem quis tellus. Sed enim diam, congue sed elit non, fermentum mollis quam. Ut lectus nisi, ornare id tortor vitae, posuere feugiat turpis. In eu quam nibh. Sed aliquet accumsan nisi ac semper. Phasellus eu dictum mi. Sed eget porttitor enim. Cras tempus condimentum tortor, a faucibus dolor euismod sed. Vivamus sollicitudin est in malesuada pulvinar. Fusce fermentum enim eu est rutrum, vel malesuada risus consectetur. Mauris id est vitae lectus convallis pulvinar.\r\n\r\nDonec facilisis libero non pretium laoreet. Proin tempor erat at felis placerat finibus. In euismod, leo nec viverra euismod, lorem eros accumsan mauris, vel lacinia nisl tortor at lectus. Aliquam erat volutpat. Donec dictum lectus a ullamcorper gravida. Phasellus non magna erat. Fusce ligula turpis, tempus vitae ligula sit amet, ullamcorper vestibulum purus. Morbi elit leo, ultrices ac dolor eu, euismod pretium justo. Etiam non orci pharetra, tempus velit sit amet, sollicitudin eros. Integer venenatis, orci sit amet congue tempus, nisi lectus iaculis metus, nec porta ex augue vitae velit. Curabitur auctor erat in justo iaculis gravida. Ut vestibulum lorem eu finibus interdum.\r\n\r\nNulla pretium dignissim sapien a aliquam. Vivamus eget nisl augue. Cras ut magna nisi. In pulvinar urna felis, id volutpat orci ullamcorper non. Etiam eget leo augue. Nam vitae libero metus. Duis et velit sit amet leo interdum efficitur non eget risus. Morbi luctus maximus tincidunt. Nunc bibendum nunc vitae sodales dapibus. Nunc id auctor turpis. Pellentesque leo eros, gravida non dolor a, ultricies egestas diam. Aliquam vel risus vitae nisi ornare imperdiet commodo vitae purus.\r\n\r\nMauris feugiat interdum turpis, sed sodales nisi feugiat a. Suspendisse potenti. Nullam tempor facilisis sem non tempor. Vestibulum posuere facilisis diam, et aliquam tellus mollis ac. Vivamus dictum viverra lorem vel pretium. Aenean pretium libero sed nisl venenatis, at ornare mi ullamcorper. Phasellus gravida arcu in purus accumsan auctor. Aliquam non augue ut mauris euismod accumsan et sed nisl. Morbi interdum tellus in mollis tempor. Pellentesque vel nisi mollis, fringilla metus sit amet, mollis arcu. Proin varius nibh urna, at fringilla ipsum pharetra ac. Integer a lacus non nisi accumsan elementum. Duis vitae sapien eget erat blandit dignissim. Donec risus neque, tincidunt at consequat sed, scelerisque eget enim. Aliquam vel nunc posuere, fringilla nunc id, gravida mi. Curabitur laoreet nulla tortor, vel blandit lectus laoreet non.\r\n\r\nCurabitur non elit mattis augue aliquet efficitur. Integer sit amet varius magna, eget accumsan turpis. Curabitur ut consequat dui. In rutrum nulla urna, ut posuere risus euismod nec. Praesent pellentesque tristique ante vel porttitor. Praesent commodo arcu id ligula interdum vulputate. Proin vitae fringilla mi, id consectetur diam. Vivamus maximus purus sit amet odio ullamcorper facilisis. Fusce placerat leo id dolor tincidunt elementum. Nunc congue venenatis neque. Nam eget imperdiet erat. Sed eget dictum nibh, id sodales massa. Nunc dapibus lectus nec nunc lobortis mollis. In tempus enim quis metus molestie aliquet. Duis venenatis aliquet massa, sit amet consectetur mauris euismod vel.\r\n\r\nDonec ac ligula ante. Nam lacinia, arcu at fringilla ultrices, erat dui rhoncus orci, vel tempus metus est a dui. Integer tincidunt vestibulum maximus. Etiam ligula urna, interdum non elementum ut, vulputate eget ipsum. Duis eu diam massa. Integer ligula tortor, hendrerit vel condimentum quis, venenatis eget mi. Maecenas eu sem at felis tempor vulputate quis eu nunc. Donec aliquet quam vel rhoncus tristique. Mauris tincidunt neque nec sem venenatis semper. Integer accumsan urna in nisi fermentum, vitae aliquam lorem faucibus. Nam eget scelerisque nisi, a rutrum massa. In vel felis eget augue blandit mattis. Proin in arcu vestibulum libero dignissim varius. Duis sit amet enim ut metus ultrices tristique. Praesent non arcu et odio sodales vehicula ut eu enim.\r\n\r\nCurabitur accumsan purus sit amet commodo dapibus. Maecenas non urna sed nulla mattis fermentum. Proin vel sem ac odio bibendum dignissim. Nulla mattis, lacus sed sollicitudin euismod, elit quam lacinia lorem, vel fringilla turpis lorem non est. Donec ut consequat erat. Nullam at congue odio. Donec lacus metus, finibus finibus urna in, porta lobortis orci. Donec consequat elit ut sem posuere gravida.\r\n\r\nDuis volutpat libero quis felis mollis, sit amet luctus lorem blandit. Etiam finibus risus non lacus lacinia, sit amet lacinia lorem auctor. Vestibulum eu fermentum felis. Etiam id odio commodo velit varius ultricies non eget augue. Vivamus non leo posuere ligula semper mattis. Phasellus eleifend fringilla justo vel vehicula. Nullam tincidunt sollicitudin condimentum. Aenean rutrum, massa sed consequat auctor, ipsum ipsum mollis purus, nec semper metus ex a nisl. Quisque ut maximus quam. Nulla interdum nec sapien eget ultricies. Suspendisse potenti. Vivamus aliquam luctus malesuada. Nunc molestie turpis quis metus egestas accumsan. Integer laoreet dui sit amet quam tincidunt, sed pellentesque tortor lobortis. Maecenas facilisis eros sed ex sollicitudin, vitae eleifend ligula ultricies. Vestibulum a dolor eleifend, cursus sem at, varius velit.\r\n\r\nMauris iaculis nisl risus, et elementum tortor aliquam mattis. Etiam vehicula hendrerit dui. Etiam auctor elementum bibendum. Donec et interdum justo. Fusce posuere ac elit eget dapibus. Curabitur tempor congue tortor vitae venenatis. Curabitur hendrerit pretium augue quis maximus. Duis non rutrum quam, sed viverra libero. Cras faucibus dui id nunc dignissim efficitur. Proin volutpat odio ut tempus ornare. Phasellus ac ex ac dui sodales ullamcorper eu vitae orci. Duis eu arcu quis nibh mollis mattis rhoncus in nisi. Donec sollicitudin convallis tortor, accumsan porttitor dui consequat ut. Vestibulum id dignissim tortor.\r\n\r\nSuspendisse sed cursus arcu, eget accumsan urna. Morbi varius, risus nec maximus maximus, urna nisi pretium augue, eu viverra nunc arcu et massa. Sed luctus elementum nulla sit amet dapibus. Praesent condimentum arcu quis convallis laoreet. Ut eu est vel nibh varius vulputate. Fusce at congue magna. Nullam sed sem gravida, dictum nisi id, aliquet ante. Donec sit amet consequat urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean aliquet diam non ante suscipit, et commodo purus tempus. Integer tempus varius gravida. Sed venenatis vehicula bibendum. Maecenas sed purus sagittis, rhoncus libero quis, rutrum augue.\r\n\r\nIn a nibh nec elit facilisis hendrerit sit amet vel est. Proin porttitor malesuada massa, convallis tempus ex ullamcorper sit amet. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus sem tellus, molestie nec sem dapibus, dapibus rhoncus lacus. Maecenas pretium arcu vitae enim fringilla suscipit. Sed et augue posuere, ultricies felis a, ultricies massa. In at commodo lacus, quis aliquam augue. Maecenas quis ornare augue, ut maximus arcu. Nam ornare rutrum erat nec varius. Aenean ligula felis, luctus semper sapien vitae, cursus pulvinar quam. Pellentesque ultrices sit amet sapien in sollicitudin.\r\n\r\nInteger sed feugiat mauris. Phasellus sit amet finibus tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ultricies arcu id est lacinia vestibulum. Quisque id nulla non urna scelerisque semper. Morbi a fringilla magna. In lobortis tincidunt purus, et sagittis est ullamcorper id. Praesent eget nisi lacus. Nam lobortis erat eros, sed congue arcu semper et. Donec ut pharetra massa, a consequat magna. Nullam malesuada ex non nisi venenatis, vestibulum viverra magna scelerisque. Phasellus elementum lorem tincidunt enim ornare ultricies.\r\n\r\nCurabitur id orci non libero luctus aliquet. Phasellus ornare placerat suscipit. Pellentesque sagittis tincidunt maximus. Integer nec risus mattis, pulvinar leo vel, lacinia est. Etiam quis pellentesque tellus. Etiam nec augue consectetur, gravida diam vitae, facilisis mi. Maecenas sodales tempor urna non pulvinar. Phasellus nec augue eleifend, fermentum nunc at, mollis tortor. Mauris lacinia augue et turpis eleifend mollis. Mauris nec lorem eu dolor volutpat scelerisque. Nunc dignissim quam sed lectus egestas pellentesque. Maecenas lobortis sapien non nisl commodo laoreet. Proin finibus justo tortor, a aliquam erat sodales at. Curabitur egestas vitae urna non sollicitudin. Nam facilisis ante sed purus mattis vestibulum. Suspendisse turpis nulla, laoreet non nisi eget, finibus interdum magna.\r\n\r\nAenean sed magna tortor. Quisque velit dui, vehicula quis ante vitae, convallis porttitor enim. Quisque sed nisi a massa porttitor placerat. Pellentesque ac neque pretium, tempus massa feugiat, fringilla est. Morbi pretium ex purus, nec pulvinar augue vestibulum in. Proin ac mi nunc. Fusce et elit cursus, dictum orci et, ultrices sapien. Donec in felis id elit aliquet fermentum sodales in tellus. Vestibulum nec enim bibendum, bibendum mi ac, tempor purus. Aliquam cursus et lectus nec vestibulum. Cras arcu diam, fringilla id dignissim et, ultrices vel leo. Sed sapien turpis, placerat sed quam eu, maximus placerat nulla. Duis at ipsum urna.\r\n\r\nDonec eleifend porttitor tellus, vitae finibus nulla pharetra id. Praesent at lacinia orci, id luctus augue. Suspendisse aliquet egestas est, in accumsan sem scelerisque non. Proin gravida porttitor interdum. Vivamus eu augue a felis fermentum pellentesque. Aliquam libero metus, gravida sit amet vulputate vitae, aliquet commodo odio. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\r\n\r\nAliquam erat volutpat. Aenean placerat mi vel velit porta faucibus. Nullam eget turpis nulla. Aliquam aliquet tortor at orci efficitur fringilla. Morbi vitae maximus massa. Aenean tincidunt elit non elit ullamcorper condimentum. Donec tincidunt urna elit, ac bibendum odio euismod et. Duis elementum nibh eget magna molestie varius. Duis ac ornare massa, quis hendrerit sapien. Ut blandit ut diam eu ornare. Nulla at enim a ante ultricies bibendum nec at quam.\r\n\r\nMauris nec efficitur nulla, ac molestie nunc. Nam placerat nunc id dapibus sodales. Mauris ac elit vitae lorem venenatis suscipit. Suspendisse sit amet augue quam. Etiam bibendum mattis nunc laoreet accumsan. Nunc efficitur imperdiet ante in venenatis. Cras vehicula consequat ipsum, in faucibus velit consequat eget. Integer varius magna metus, eget venenatis nisl congue at. Nullam et velit ut nisl pharetra luctus a eu massa. Duis lobortis tempor elit at tincidunt. Donec urna sem, laoreet sit amet felis eget, sodales vehicula ante. Aliquam in risus vel arcu varius convallis. Integer rutrum massa at elit gravida rutrum eget sit amet nunc. Phasellus quis auctor metus, eu ullamcorper mi.\r\n\r\nNunc at elit sed leo porta vulputate quis sit amet magna. Phasellus condimentum interdum vulputate. Aliquam in urna sed magna porttitor luctus. Sed tempus ex vel odio blandit, non feugiat lorem venenatis. Nulla cursus venenatis felis at dapibus. Nullam lorem purus, aliquet id tristique sit amet, dapibus non enim. Aenean finibus libero ac justo commodo blandit. Suspendisse venenatis ut metus pulvinar posuere.\r\n\r\nMauris ullamcorper quam et magna scelerisque, vel tempus sapien laoreet. Phasellus sem leo, pellentesque non augue eu, pharetra ultrices felis. Sed non dignissim lectus, ac egestas dolor. Fusce id libero tortor. Integer efficitur turpis non euismod aliquam. Curabitur elementum mollis tellus, vel accumsan dolor. Quisque tempus, nisi eu gravida pretium, erat urna aliquet enim, vitae eleifend quam justo et nibh. Donec iaculis in nulla faucibus pretium. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.\r\n\r\nInteger ultrices nisi eu est fringilla blandit. Aenean id enim nunc. Nullam eu eros in erat rhoncus facilisis eget sit amet nulla. Phasellus tristique at velit id ornare. Morbi odio felis, cursus eu lacinia eget, consequat nec sem. Pellentesque feugiat, velit in accumsan auctor, dui leo posuere erat, auctor faucibus nunc tortor ut dui. Nam vitae iaculis mauris. Maecenas in turpis sed diam dapibus tempor. Sed ac posuere mi.\r\n\r\nPhasellus facilisis arcu ac facilisis molestie. Maecenas egestas orci leo, sit amet mollis tortor tincidunt volutpat. Pellentesque ut dapibus justo, pellentesque pulvinar mauris. Quisque in tempus dui. Aliquam lorem erat, fermentum rutrum nulla vel, blandit dictum neque. Aenean maximus quis dolor non congue. Phasellus euismod et enim ut tempus. In ultrices, dui ut efficitur tempus, odio urna dignissim justo, et molestie nunc sem et urna. Sed aliquet vel neque ut accumsan. Quisque id malesuada turpis. Praesent pretium turpis ex, sit amet euismod mauris maximus eget. Etiam malesuada risus in elit mattis, id eleifend mauris maximus. Integer feugiat justo est, id viverra orci tempus a. Phasellus quis nisl felis.",
  "name": "big-descr"
}'

(unrelated to HR import functions from this PR)

Based on the fact I could replicate these errors beyond the MR python client, I would say these are unrelated but affecting limitations.

@isinyaaa
Copy link
Contributor Author

isinyaaa commented Jan 9, 2024

Importing the README.md file as a field won't really be possible due to limitations on the MLMD server, but I'd argue that it makes sense to pursue the idea of having it as a separate Artifact, as discussed with @tarilabs @lampajr @rareddy . However, what artifact type should that be? Moreover, where should we store that data?

@tarilabs
Copy link
Member

tarilabs commented Jan 10, 2024

Importing the README.md file as a field won't really be possible due to limitations on the MLMD server, but I'd argue that it makes sense to pursue the idea of having it as a separate Artifact, as discussed with @tarilabs @lampajr @rareddy . However, what artifact type should that be? Moreover, where should we store that data?

I'd recommend to default description to the first arbitrary-length characters (say 100? followed by ellipsis (...)) so the end-user can also always override this default if need be during HF import.

For the DocArtifact I agree with Dhiraj is likely another type of artifact, but we need to sync that choice on all ends (backend, REST, and Python) and I would recommend capturing that in a following JIRA/PR.
wdyt?

@isinyaaa
Copy link
Contributor Author

Importing the README.md file as a field won't really be possible due to limitations on the MLMD server, but I'd argue that it makes sense to pursue the idea of having it as a separate Artifact, as discussed with @tarilabs @lampajr @rareddy . However, what artifact type should that be? Moreover, where should we store that data?

I'd recommend to default description to the first arbitrary-length characters (say 100? followed by ellipsis (...)) so the end-user can also always override this default if need be during HF import.

This can be left for later, as discussed privately, due to the additional complexity.

For the DocArtifact I agree with Dhiraj is likely another type of artifact, but we need to sync that choice on all ends (backend, REST, and Python) and I would recommend capturing that in a following JIRA/PR. wdyt?

Documented on #263.

Signed-off-by: Isabella Basso do Amaral <[email protected]>
Signed-off-by: Isabella Basso do Amaral <[email protected]>
As discussed on [1], there's no need for a tags property just yet, and
there's also no agreed format for list metadata, so let's just get rid
of it.

[1]: https://github.com/opendatahub-io/model-registry/pull/260#discussion_r1441786749

Signed-off-by: Isabella Basso do Amaral <[email protected]>
Signed-off-by: Isabella Basso do Amaral <[email protected]>
Signed-off-by: Isabella Basso do Amaral <[email protected]>
@isinyaaa
Copy link
Contributor Author

How should we deal with versions? I'm thinking about users that want to update a model after the initial import, so we probably could default the version to be the latest commit ID. wdyt?

@dhirajsb
Copy link
Contributor

The user should provide version labels explicitly. Commit IDs should not be used for version labels, since model version labels are more like Docker image labels. And a registered model version is more like a Docker image release.
Keep in mind that we are not considering experiments and runs yet, for which commit ids would be more suitable as run labels.

Signed-off-by: Isabella Basso do Amaral <[email protected]>
@isinyaaa isinyaaa merged commit 0497cf4 into opendatahub-io:main Jan 17, 2024
6 checks passed
isinyaaa referenced this pull request Jan 17, 2024
As discussed on [1], there's no need for a tags property just yet, and
there's also no agreed format for list metadata, so let's just get rid
of it.

[1]: https://github.com/opendatahub-io/model-registry/pull/260#discussion_r1441786749

Signed-off-by: Isabella Basso do Amaral <[email protected]>
@isinyaaa isinyaaa deleted the hf-imports branch January 17, 2024 18:20
Copy link
Member

@tarilabs tarilabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested latest using https://huggingface.co/tarilabs/mnist/tree/v1.nb20231206162408

image

and result indexed on MR:

image

registered_model:

curl --silent -X 'GET' \
  "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \
  -H 'accept: application/json' | jq .items
[
  {
    "createTimeSinceEpoch": "1705514870832",
    "customProperties": {},
    "id": "37",
    "lastUpdateTimeSinceEpoch": "1705514870832",
    "name": "tarilabs-mnist-from-hf",
    "state": "LIVE"
  },
...

model_version:

curl --silent -X 'GET' \
  "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/37/versions?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \
  -H 'accept: application/json' | jq .items
[
  {
    "author": "tarilabs",
    "createTimeSinceEpoch": "1705514871435",
    "customProperties": {
      "license": {
        "string_value": "apache-2.0"
      },
      "model_author": {
        "string_value": "tarilabs"
      },
      "model_origin": {
        "string_value": "huggingface_hub"
      },
      "repo": {
        "string_value": "tarilabs/mnist"
      },
      "source_uri": {
        "string_value": "https://huggingface.co/tarilabs/mnist/resolve/main/mnist.onnx"
      }
    },
    "description": "testing out PR 260",
    "id": "38",
    "lastUpdateTimeSinceEpoch": "1705514871435",
    "name": "v1.nb20231206162408",
    "state": "LIVE"
  }
]

model_artifact:

curl --silent -X 'GET' \
  "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/38/artifacts" \
  -H 'accept: application/json' | jq .items
[
  {
    "artifactType": "model-artifact",
    "createTimeSinceEpoch": "1705514872127",
    "customProperties": {},
    "id": "7",
    "lastUpdateTimeSinceEpoch": "1705514872127",
    "modelFormatName": "onnx",
    "modelFormatVersion": "1",
    "name": "tarilabs-mnist-from-hf",
    "state": "UNKNOWN",
    "storagePath": "mnist.onnx",
    "uri": "https://huggingface.co/tarilabs/mnist/resolve/main/mnist.onnx"
  }
]

@lampajr does it match your expectations on entity attributes? Seems to me it's coherent/as expected.

@lampajr
Copy link
Contributor

lampajr commented Jan 17, 2024

@lampajr does it match your expectations on entity attributes? Seems to me it's coherent/as expected.

+1 it seems coherent to me too, everything is properly populated (worth to note that storageKey in modelArtifact is correctly nil as we are referencing external model)

dhirajsb pushed a commit to dhirajsb/model-registry that referenced this pull request Jan 20, 2025
…tend (opendatahub-io#260)

Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 18.2.0 to 18.3.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v18.3.1/packages/react-dom)

---
updated-dependencies:
- dependency-name: react-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants