From f5aecd61d24799306bc79a7fb2ff3c68b5bde0e1 Mon Sep 17 00:00:00 2001 From: zhichao-aws Date: Tue, 13 Aug 2024 13:15:12 +0800 Subject: [PATCH 1/9] add blog content Signed-off-by: zhichao-aws --- _posts/2024-08-19-neural-sparse-v2-models.md | 155 ++++++++++++++++++ .../cpu_ingest.png | Bin 0 -> 27360 bytes .../cpu_search.png | Bin 0 -> 35669 bytes .../gpu_ingest.png | Bin 0 -> 25158 bytes .../gpu_search.png | Bin 0 -> 33098 bytes 5 files changed, 155 insertions(+) create mode 100644 _posts/2024-08-19-neural-sparse-v2-models.md create mode 100644 assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_ingest.png create mode 100644 assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_search.png create mode 100644 assets/media/blog-images/2024-08-19-neural-sparse-v2-models/gpu_ingest.png create mode 100644 assets/media/blog-images/2024-08-19-neural-sparse-v2-models/gpu_search.png diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md new file mode 100644 index 0000000000..1b3a8aa341 --- /dev/null +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -0,0 +1,155 @@ +--- +layout: post +title: Advancing Search Quality and Inference Speed with v2 Series Neural Sparse Models +authors: + - zhichaog + - congguan + - yych + - dylantong +date: 2024-08-19 +categories: + - technical-posts +has_math: true +meta_keywords: OpenSearch semantic search, neural sparse search, semantic sparse retrieval +meta_description: Introducing the neural sparse v2 series model, and demonstrate the benchmark result on ingestion performance, search performance and search relevance. + +excerpt: Introducing the neural sparse v2 series model, and demonstrate the benchmark result on ingestion performance, search performance and search relevance. +featured_blog_post: true +featured_image: false # /assets/media/blog-images/__example__image__name.jpg +--- + +Neural sparse search is a novel, efficient method of semantic retrieval that was [introduced in OpenSearch 2.11](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/). The sparse encoding models encode text into (token, weight) entries, and OpenSearch builds indexes and perform searches using Lucene's inverted index. Neural sparse search is efficient and have strong generalization ability in out-of-domain(OOD) scenarios. We are thrilled to announce the release of our v2 series neural sparse models: + +- v2-distill model: this model **reduces the model parameters to 0.5x** and reduce cost as a result of proportionally less memory requirements. It increases the ingestion throughput **1.39x** on GPU and **1.74x** on CPU. v2-distill arch is supported on both doc-only and bi-encoder modes. +- v2-mini model: this model **reduces the model parameters to 0.25x** and reduce cost as a result of proportionally less memory requirements. It increases the ingestion throughput **1.74x** on GPU and **4.18x** on CPU. v2-mini arch is supported on doc-only mode. + +Besides, all v2 models achieve **better search relevance**. The overall comparison between them and the v1 models is shown in the table below. All v2 models are now available at both [OpenSearch](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models) and [Hugging Face](https://huggingface.co/opensearch-project). + +| Model | Inference-free for Retrieval | Model Parameters | AVG NDCG@10 | +|-------|------------------------------|------------------|-------------| +| [opensearch-neural-sparse-encoding-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v1) | | 133M | 0.524 | +| [opensearch-neural-sparse-encoding-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v2-distill) | | 67M | 0.528 | +| [opensearch-neural-sparse-encoding-doc-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v1) | ✔️ | 133M | 0.490 | +| [opensearch-neural-sparse-encoding-doc-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-distill) | ✔️ | 67M | 0.504 | +| [opensearch-neural-sparse-encoding-doc-v2-mini](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-mini) | ✔️ | 23M | 0.497 | + +## The Evolution from v1 Series to v2 Series of Models + +### Limitations for v1 Models + +For neural sparse search, the sparse encoding model is a critical component as it influences how documents are scored and rank. In other words, it directly influences the relevancy of your search results. Moreover, the inference speed of the model also directly affects the ingestion throughput and the client-side search latency of bi-encoder mode. When we released the neural sparse feature in OpenSearch, we also launched two neural sparse models, supporting doc-only and bi-encoder modes respectively. + +The biggest challenge for v1 models is the large model size. The v1 series models are tuned from the BERT-base model, which is a 12-layer transformer model with 133 million parameters. Compared with popular dense embedding models like [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b) and [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2), the inference cost of the v1 models is 2x even 4x higher. As a result, for the v2 series models, there is an urgent need to reduce the number of model parameters without compromising search accuracy. + +### Knowledge Distillation from Ensemble Heterogeneous Teacher Models + +For neural models, performance is tightly coupled with the number of parameters. When using smaller backbone, we need to enhance the training algorithm to compensate for the performance drop. For the retrieval task, the common technique is to **pre-training** and **knowledge distillation**: + +- Pre-training: Training models using massive amount of data, which is usually constructed by rules. For example, (title, body) pairs in news articles or (question, answer) pairs on Q&A websites. Pre-training enhances the model’s search relevance and generalization ability. +- Knowledge distillation: Some models have strong performance but are inefficient in the form of large model size or inefficient structure(e.g. cross-encoder rerankers). Distillation is a technique that transfers knowledge from these teacher models to smaller ones with the aim to preserve high performance while discarding the inefficiencies. + +For existing dense retrievers, pre-training was usually conducted with the infoNCE loss, which was proved to improve the alignment and uniformity of dense representations. However, for sparse embeddings especially doc-only mode, we find that infoNCE loss doesn't enhance the model as it does for dense models. In contrast, knowledge distillation loss is a more effective optimization objective. The challenge is to find a teacher model which are strong enough(where siamese encoders fail) and efficient enough to predict on the large-scale pre-training dataset(where cross-encoders fail). Inspired by the drastic performance boost from the [hybrid search of dense and lexical(sparse) approach](https://opensearch.org/blog/hybrid-search/), we innovatively propose to ensemble bi-encoder learned sparse retriever with Siamese dense models to construct a strong teacher model. It combines the strength of heterogenous retrievers, and is efficient enough to apply on pre-training. We plan to publish a paper about the training procedure and will discuss more details in it. The pre-training with knowledge distillation allow us to safely reduce the number of model parameters without compromising performance. + + +Overall, thanks to pre-training on massive corpus[^1], the **v2 series models** have further **improved search relevance** while significantly **reducing the number of model parameters**. We have released distill-BERT-based models for both doc-only and bi-encoder modes (same size as [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b)), and a miniLM-based model for the doc-only mode (same size as [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)). + +## Model Inference Speed Up + +The v2 model continues to use the transformer architecture. It reduces the number of parameters by decreasing the number of layers and the hidden dimension. Therefore, we can get higher ingestion throughput and lower search latency with the smaller v2 models. We benchmark the v2 models at the scenarios of ingestion and search. We use the MS MARCO passage retrieval dataset. We use a OpenSearch 2.16 cluster with 3 nodes of r7a.8xlarge EC2 instances. + +**GPU deployment.** We use a SageMaker GPU endpoint to host the neural sparse model and use it as a remote connector ([code script](https://github.com/zhichao-aws/neural-search/tree/neural_sparse_sagemaker/neural_sparse_sagemaker_example)). We use a **g5.xlarge** GPU instance to host the model. +**CPU deployment.** The model is deployed on **all 3 nodes** in the cluster. + +### Ingestion + +In this experiments, we set the `batch_size` of `sparse_encoding` ingestion processor to 2. We record the mean ingestion throughput and the P99 client-side latency for the bulk API. We use 20 clients to do ingestion in this section. + +#### Remote deployment using GPU + +Bulk size is set to 24. The experiment results is listed below. Compared with the v1 model, the **v2-distill** model increase the mean throughput **1.39x** and the **v2-mini** model increase the mean throughput **1.74x**. + + + +#### Local deployment using CPU + +Bulk size is set to 8. Compared with the v1 model, the **v2-distill** model increase the mean throughput **1.58x** and the **v2-mini** model increase the mean throughput **4.18x**. + + + +### Search + +In this experiments, we ingest 1 million documents into the index, and use 20 clients to search in concurrent. We record the search client-side P99 latency and model inference P99 latency. We test the search performance for the **bi-encoder** mode. + +#### Remote deployment using GPU + +Compared with the v1 model, the **v2-distill** model decrease the search client-side latency by **11.7%** and model inference latency by **23%**. + + + +#### Local deployment using CPU + +Compared with the v1 model, the **v2-distill** model decrease the search client-side latency by **30.2%** and model inference latency by **33.3%**. + + + +## Search Relevance Benchmark + +Consistent with our previous [blog](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we benchmark the model search relevance on subset of BEIR benchmark. The detailed search relevance is shown in the table below. All v2-series models outperform the v1 model with the same architecture. + +
+ +| Model | Average | Trec Covid | NFCorpus | NQ | HotpotQA | FiQA | ArguAna | Touche | DBPedia | SCIDOCS | FEVER | Climate FEVER | SciFact | Quora | +|-------|---------|------------|----------|----|----------|------|---------|--------|---------|---------|-------|---------------|---------|-------| +| [opensearch-neural-sparse-encoding-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v1) | 0.524 | 0.771 | 0.360 | 0.553 | 0.697 | 0.376 | 0.508 | 0.278 | 0.447 | 0.164 | 0.821 | 0.263 | 0.723 | 0.856 | +| [opensearch-neural-sparse-encoding-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v2-distill) | 0.528 | 0.775 | 0.347 | 0.561 | 0.685 | 0.374 | 0.551 | 0.278 | 0.435 | 0.173 | 0.849 | 0.249 | 0.722 | 0.863 | +| [opensearch-neural-sparse-encoding-doc-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v1) | 0.490 | 0.707 | 0.352 | 0.521 | 0.677 | 0.344 | 0.461 | 0.294 | 0.412 | 0.154 | 0.743 | 0.202 | 0.716 | 0.788 | +| [opensearch-neural-sparse-encoding-doc-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-distill) | 0.504 | 0.690 | 0.343 | 0.528 | 0.675 | 0.357 | 0.496 | 0.287 | 0.418 | 0.166 | 0.818 | 0.224 | 0.715 | 0.841 | +| [opensearch-neural-sparse-encoding-doc-v2-mini](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-mini) | 0.497 | 0.709 | 0.336 | 0.510 | 0.666 | 0.338 | 0.480 | 0.285 | 0.407 | 0.164 | 0.812 | 0.216 | 0.699 | 0.837 | + +
+ +## Register and Deploy V2 Models + +The v2 series sparse encoding models can be registered as OpenSearch-provided pretrained models supported by ml-commons plugin. The register APIs are listed as follows. + +For ingestion and search with sparse model deployed, please check the [documentation](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). + +### Register&Deploy models of doc-only mode + +```json +## register sparse_encoding model for ingestion +POST /_plugins/_ml/models/_register?deploy=true +{ + "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v2-distill", + "version": "1.0.0", + "model_format": "TORCH_SCRIPT" +} + +## register sparse_tokenize model for search +POST /_plugins/_ml/models/_register?deploy=true +{ + "name": "amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1", + "version": "1.0.1", + "model_format": "TORCH_SCRIPT" +} + +## get model_id from task_ids returned by register model API +GET /_plugins/_ml/tasks/{task_id} +``` + +### Register&Deploy models of bi-encoder mode + +```json +## register sparse_encoding model for ingestion and search +POST /_plugins/_ml/models/_register?deploy=true +{ + "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill", + "version": "1.0.0", + "model_format": "TORCH_SCRIPT" +} + +## get model_id from task_ids returned by register model API +GET /_plugins/_ml/tasks/{task_id} +``` + +[^1]: We pick a subset of [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data) collected by sentence-transformers. All datasets overlapped with BEIR are excluded to keep a zero-shot setting for the evaluation. \ No newline at end of file diff --git a/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_ingest.png b/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_ingest.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fb835b45b41565d05cb9e95cf6cd7f9e42fe2d GIT binary patch literal 27360 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 literal 0 HcmV?d00001 diff --git a/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_search.png b/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/cpu_search.png new file mode 100644 index 0000000000000000000000000000000000000000..45c1d2c2335c4f7976874311867e58575ba9ffce GIT binary patch literal 35669 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 literal 0 HcmV?d00001 diff --git a/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/gpu_search.png b/assets/media/blog-images/2024-08-19-neural-sparse-v2-models/gpu_search.png new file mode 100644 index 0000000000000000000000000000000000000000..066b30e1de0e380f7c6e6b1216be4b248e3c1dd3 GIT binary patch literal 33098 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 Date: Wed, 14 Aug 2024 11:56:29 +0800 Subject: [PATCH 2/9] add further reading Signed-off-by: zhichao-aws --- ...document-retrieval-with-sparse-semantic-encoders.md | 10 +++++++++- ...into-faster-semantic-sparse-retrieval-in-OS-2.12.md | 8 ++++++++ ...-Introducing-a-neural-sparse-two-phase-algorithm.md | 7 +++++++ _posts/2024-08-19-neural-sparse-v2-models.md | 8 ++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/_posts/2023-12-05-improving-document-retrieval-with-sparse-semantic-encoders.md b/_posts/2023-12-05-improving-document-retrieval-with-sparse-semantic-encoders.md index 8b243cf669..a94b124f69 100644 --- a/_posts/2023-12-05-improving-document-retrieval-with-sparse-semantic-encoders.md +++ b/_posts/2023-12-05-improving-document-retrieval-with-sparse-semantic-encoders.md @@ -479,4 +479,12 @@ Use the following recommendations to select a sparse encoding model: - For more information about neural sparse search, see [Neural sparse search](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). - For an end-to-end neural search tutorial, see [Neural search tutorial](https://opensearch.org/docs/latest/search-plugins/neural-search-tutorial/). - For a list of all search methods OpenSearch supports, see [Search methods](https://opensearch.org/docs/latest/search-plugins/index/#search-methods). -- Provide your feedback on the [OpenSearch Forum](https://forum.opensearch.org/). \ No newline at end of file +- Provide your feedback on the [OpenSearch Forum](https://forum.opensearch.org/). + +## Further reading + +Read more about neural sparse search: + +1. [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) +1. [Introducing the neural sparse two-phase algorithm]({{site.baseurl}}/blog/Introducing-a-neural-sparse-two-phase-algorithm) +1. [Advancing Search Quality and Inference Speed with v2 Series Neural Sparse Models]({{site.baseurl}}/blog/neural-sparse-v2-models) \ No newline at end of file diff --git a/_posts/2024-06-11-A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12.md b/_posts/2024-06-11-A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12.md index 498c52de05..5caefc200c 100644 --- a/_posts/2024-06-11-A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12.md +++ b/_posts/2024-06-11-A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12.md @@ -146,3 +146,11 @@ In this blog post, we explored the performance of neural sparse search and showe 1. Model inference is a throughput bottleneck for neural sparse ingestion and bi-encoder search. Using a GPU can significantly accelerate model inference, leading to a higher throughput and better cost/performance ratio. This study provides insights to help you scale your resources effectively when migrating from BM25 to neural sparse search in a new cluster. Refer to the quantitative data to estimate the workload requirements for your specific use case. If you require a high ingestion throughput or a high query throughput for searching in the bi-encoder mode, we recommend using a GPU. For more information about configuring neural sparse search, see the [Neural sparse search documentation](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). + +## Further reading + +Read more about neural sparse search: + +1. [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) +1. [Introducing the neural sparse two-phase algorithm]({{site.baseurl}}/blog/Introducing-a-neural-sparse-two-phase-algorithm) +1. [Advancing Search Quality and Inference Speed with v2 Series Neural Sparse Models]({{site.baseurl}}/blog/neural-sparse-v2-models) \ No newline at end of file diff --git a/_posts/2024-08-07-Introducing-a-neural-sparse-two-phase-algorithm.md b/_posts/2024-08-07-Introducing-a-neural-sparse-two-phase-algorithm.md index caf746127f..adc208fa10 100644 --- a/_posts/2024-08-07-Introducing-a-neural-sparse-two-phase-algorithm.md +++ b/_posts/2024-08-07-Introducing-a-neural-sparse-two-phase-algorithm.md @@ -120,3 +120,10 @@ PUT //_settings For more information about the two-phase processor, see [Neural sparse query two-phase processor](https://opensearch.org/docs/latest/search-plugins/search-pipelines/neural-sparse-query-two-phase-processor/). +## Further reading + +Read more about neural sparse search: + +1. [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) +1. [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) +1. [Advancing Search Quality and Inference Speed with v2 Series Neural Sparse Models]({{site.baseurl}}/blog/neural-sparse-v2-models) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 1b3a8aa341..24bf765f00 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -152,4 +152,12 @@ POST /_plugins/_ml/models/_register?deploy=true GET /_plugins/_ml/tasks/{task_id} ``` +## Further reading + +Read more about neural sparse search: + +1. [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) +1. [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) +1. [Introducing the neural sparse two-phase algorithm]({{site.baseurl}}/blog/Introducing-a-neural-sparse-two-phase-algorithm) + [^1]: We pick a subset of [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data) collected by sentence-transformers. All datasets overlapped with BEIR are excluded to keep a zero-shot setting for the evaluation. \ No newline at end of file From 38f8575cd928437ff3d63d315c72aeb032b66d75 Mon Sep 17 00:00:00 2001 From: Fanit Kolchina Date: Fri, 16 Aug 2024 17:02:39 -0400 Subject: [PATCH 3/9] Doc review Signed-off-by: Fanit Kolchina --- _posts/2024-08-19-neural-sparse-v2-models.md | 166 ++++++++++--------- 1 file changed, 91 insertions(+), 75 deletions(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 24bf765f00..41009923f4 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -1,31 +1,32 @@ --- layout: post -title: Advancing Search Quality and Inference Speed with v2 Series Neural Sparse Models +title: Improving search efficiency and accuracy with the newest v2 neural sparse models authors: - zhichaog - congguan - yych - dylantong + - kolchfa date: 2024-08-19 categories: - technical-posts -has_math: true +has_science_table: true meta_keywords: OpenSearch semantic search, neural sparse search, semantic sparse retrieval -meta_description: Introducing the neural sparse v2 series model, and demonstrate the benchmark result on ingestion performance, search performance and search relevance. +meta_description: Accelerating inference and improving search with v2 neural sparse encoding models -excerpt: Introducing the neural sparse v2 series model, and demonstrate the benchmark result on ingestion performance, search performance and search relevance. +excerpt: We're excited to introduce the neural sparse v2 series models---a significant upgrade that enhances performance across key metrics. Our benchmarks reveal improved ingestion speed, faster search performance, and better search relevance. featured_blog_post: true featured_image: false # /assets/media/blog-images/__example__image__name.jpg --- -Neural sparse search is a novel, efficient method of semantic retrieval that was [introduced in OpenSearch 2.11](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/). The sparse encoding models encode text into (token, weight) entries, and OpenSearch builds indexes and perform searches using Lucene's inverted index. Neural sparse search is efficient and have strong generalization ability in out-of-domain(OOD) scenarios. We are thrilled to announce the release of our v2 series neural sparse models: +Neural sparse search is a novel and efficient method for semantic retrieval, [introduced in OpenSearch 2.11](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/). Sparse encoding models encode text into (token, weight) entries, allowing OpenSearch to build indexes and perform searches using Lucene's inverted index. Neural sparse search is efficient and generalizes well in out-of-domain (OOD) scenarios. We are excited to announce the release of our v2 series neural sparse models: -- v2-distill model: this model **reduces the model parameters to 0.5x** and reduce cost as a result of proportionally less memory requirements. It increases the ingestion throughput **1.39x** on GPU and **1.74x** on CPU. v2-distill arch is supported on both doc-only and bi-encoder modes. -- v2-mini model: this model **reduces the model parameters to 0.25x** and reduce cost as a result of proportionally less memory requirements. It increases the ingestion throughput **1.74x** on GPU and **4.18x** on CPU. v2-mini arch is supported on doc-only mode. +- **v2-distill model**: This model **reduces model parameters by 50%**, resulting in lower memory requirements and costs. It **increases ingestion throughput by 1.39 on GPU and 1.74x on CPU**. The v2-distill architecture supports both doc-only and bi-encoder modes. +- **v2-mini model**: This model **reduces model parameters by 75%**, also reducing memory requirements and costs. It **increases ingestion throughput by 1.74x on GPU and 4.18x on CPU**. The v2-mini architecture supports the doc-only mode. -Besides, all v2 models achieve **better search relevance**. The overall comparison between them and the v1 models is shown in the table below. All v2 models are now available at both [OpenSearch](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models) and [Hugging Face](https://huggingface.co/opensearch-project). +Additionally, all v2 models achieve **better search relevance**. A comparison with v1 models is shown in the following table. All v2 models are now available on both [OpenSearch](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models) and [Hugging Face](https://huggingface.co/opensearch-project). -| Model | Inference-free for Retrieval | Model Parameters | AVG NDCG@10 | +| Model | Requires no inference for retrieval | Model parameters | AVG NDCG@10 | |-------|------------------------------|------------------|-------------| | [opensearch-neural-sparse-encoding-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v1) | | 133M | 0.524 | | [opensearch-neural-sparse-encoding-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v2-distill) | | 67M | 0.528 | @@ -33,70 +34,67 @@ Besides, all v2 models achieve **better search relevance**. The overall comparis | [opensearch-neural-sparse-encoding-doc-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-distill) | ✔️ | 67M | 0.504 | | [opensearch-neural-sparse-encoding-doc-v2-mini](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-mini) | ✔️ | 23M | 0.497 | -## The Evolution from v1 Series to v2 Series of Models +## From v1 series to v2 series models -### Limitations for v1 Models +The transition from v1 to v2 models in OpenSearch represents a significant advancement in neural sparse search capabilities. -For neural sparse search, the sparse encoding model is a critical component as it influences how documents are scored and rank. In other words, it directly influences the relevancy of your search results. Moreover, the inference speed of the model also directly affects the ingestion throughput and the client-side search latency of bi-encoder mode. When we released the neural sparse feature in OpenSearch, we also launched two neural sparse models, supporting doc-only and bi-encoder modes respectively. +### Limitations of v1 models -The biggest challenge for v1 models is the large model size. The v1 series models are tuned from the BERT-base model, which is a 12-layer transformer model with 133 million parameters. Compared with popular dense embedding models like [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b) and [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2), the inference cost of the v1 models is 2x even 4x higher. As a result, for the v2 series models, there is an urgent need to reduce the number of model parameters without compromising search accuracy. +For neural sparse search, the sparse encoding model is critical as it influences document scoring and ranking, directly impacting search relevance. The model’s inference speed also affects ingestion throughput and client-side search latency in bi-encoder mode. When we released neural sparse search in OpenSearch, we also launched two neural sparse models supporting doc-only and bi-encoder modes, respectively. -### Knowledge Distillation from Ensemble Heterogeneous Teacher Models +The primary challenge for v1 models is their large size. The v1 series models are based on the BERT base model, a 12-layer transformer with 133 million parameters. Compared to popular dense embedding models like [`tas-b`](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b) and [`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2), the inference cost of the v1 models is 2x to 4x higher. Therefore, reducing model parameters without compromising search accuracy became essential for the v2 series. -For neural models, performance is tightly coupled with the number of parameters. When using smaller backbone, we need to enhance the training algorithm to compensate for the performance drop. For the retrieval task, the common technique is to **pre-training** and **knowledge distillation**: +### Knowledge distillation from an ensemble of heterogeneous teacher models -- Pre-training: Training models using massive amount of data, which is usually constructed by rules. For example, (title, body) pairs in news articles or (question, answer) pairs on Q&A websites. Pre-training enhances the model’s search relevance and generalization ability. -- Knowledge distillation: Some models have strong performance but are inefficient in the form of large model size or inefficient structure(e.g. cross-encoder rerankers). Distillation is a technique that transfers knowledge from these teacher models to smaller ones with the aim to preserve high performance while discarding the inefficiencies. +In neural models, performance is closely tied to the number of parameters. When using a smaller architecture, the training algorithm must be enhanced to offset any performance drop. For retrieval tasks, common techniques include **pretraining** and **knowledge distillation**: -For existing dense retrievers, pre-training was usually conducted with the infoNCE loss, which was proved to improve the alignment and uniformity of dense representations. However, for sparse embeddings especially doc-only mode, we find that infoNCE loss doesn't enhance the model as it does for dense models. In contrast, knowledge distillation loss is a more effective optimization objective. The challenge is to find a teacher model which are strong enough(where siamese encoders fail) and efficient enough to predict on the large-scale pre-training dataset(where cross-encoders fail). Inspired by the drastic performance boost from the [hybrid search of dense and lexical(sparse) approach](https://opensearch.org/blog/hybrid-search/), we innovatively propose to ensemble bi-encoder learned sparse retriever with Siamese dense models to construct a strong teacher model. It combines the strength of heterogenous retrievers, and is efficient enough to apply on pre-training. We plan to publish a paper about the training procedure and will discuss more details in it. The pre-training with knowledge distillation allow us to safely reduce the number of model parameters without compromising performance. +- **Pretraining**: This involves training models on large datasets, often constructed using specific rules. Examples of such dataset elements are `(title, body)` pairs in news articles or `(question, answer)` pairs on Q&A websites. Pretraining enhances the model’s search relevance and ability to generalize. +- **Knowledge distillation**: Some models are powerful but suffer from inefficiencies because of their large size or complex structure. An example of such a model is the cross-encoder reranker. Distillation transfers knowledge from these teacher models to smaller ones, preserving high performance while eliminating these drawbacks. +Dense retrievers are usually pretrained using Information Noise-Contrastive Estimation (InfoNCE) loss, which improves consistency and uniformity of dense representations. However, we found that InfoNCE loss does not enhance sparse embeddings in doc-only mode as it does for dense models. Instead, knowledge distillation loss is a more effective optimization technique for sparse encoding models. Finding a suitable teacher model for large-scale pretraining is challenging. Siamese encoders are generally not strong models, while cross-encoders struggle with handling large pretraining datasets. Inspired by the performance boost from the [hybrid search of dense and lexical (sparse) approaches](https://opensearch.org/blog/hybrid-search/), we decided to combine a bi-encoder sparse retriever with Siamese dense models to create a strong teacher model. This model combines the strengths of heterogeneous retrievers and is efficient enough for pretraining. We plan to publish a paper detailing the training procedure. -Overall, thanks to pre-training on massive corpus[^1], the **v2 series models** have further **improved search relevance** while significantly **reducing the number of model parameters**. We have released distill-BERT-based models for both doc-only and bi-encoder modes (same size as [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b)), and a miniLM-based model for the doc-only mode (same size as [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)). +Pretraining with knowledge distillation allows us to reduce the number of model parameters without compromising performance. Because we performed pretraining on a massive corpus[^1], the **v2 series models** achieved **improved search relevance** while significantly **reducing the number of model parameters**. We have released distill-BERT-based models for both doc-only and bi-encoder modes (similar in size to [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b)) and a miniLM-based model for the doc-only mode (similar in size to [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)). -## Model Inference Speed Up +## Accelerating model inference -The v2 model continues to use the transformer architecture. It reduces the number of parameters by decreasing the number of layers and the hidden dimension. Therefore, we can get higher ingestion throughput and lower search latency with the smaller v2 models. We benchmark the v2 models at the scenarios of ingestion and search. We use the MS MARCO passage retrieval dataset. We use a OpenSearch 2.16 cluster with 3 nodes of r7a.8xlarge EC2 instances. +The v2 models continue to use the transformer architecture, reducing the number of parameters by decreasing the number of layers and the hidden dimension size. As a result, the smaller v2 models offer higher ingestion throughput and lower search latency. We benchmarked the v2 models in ingestion and search scenarios using the MS MARCO passage retrieval dataset on an OpenSearch 2.16 cluster with three nodes running on r7a.8xlarge EC2 instances. -**GPU deployment.** We use a SageMaker GPU endpoint to host the neural sparse model and use it as a remote connector ([code script](https://github.com/zhichao-aws/neural-search/tree/neural_sparse_sagemaker/neural_sparse_sagemaker_example)). We use a **g5.xlarge** GPU instance to host the model. -**CPU deployment.** The model is deployed on **all 3 nodes** in the cluster. +**GPU deployment**: We used a SageMaker GPU endpoint to host the neural sparse model, connecting to it using a remote connector. For complete deployment code, see [this example](https://github.com/zhichao-aws/neural-search/blob/neural_sparse_sagemaker/neural_sparse_sagemaker_example/run.ipynb). The model was hosted on a **g5.xlarge** GPU instance. +**CPU deployment**: The model was deployed on **all three nodes** in the cluster. -### Ingestion - -In this experiments, we set the `batch_size` of `sparse_encoding` ingestion processor to 2. We record the mean ingestion throughput and the P99 client-side latency for the bulk API. We use 20 clients to do ingestion in this section. +In these experiments, we set the `batch_size` of the `sparse_encoding` ingestion processor to `2`. We recorded the mean ingestion throughput and the p99 client-side latency for the Bulk API, using 20 clients for ingestion. #### Remote deployment using GPU -Bulk size is set to 24. The experiment results is listed below. Compared with the v1 model, the **v2-distill** model increase the mean throughput **1.39x** and the **v2-mini** model increase the mean throughput **1.74x**. +The bulk size was set to 24. The experiment results are listed in the following figure. Compared with the v1 model, the **v2-distill** model provided a **1.39x increase in mean throughput** and the **v2-mini** model provided a **1.74x increase in mean throughput**. #### Local deployment using CPU -Bulk size is set to 8. Compared with the v1 model, the **v2-distill** model increase the mean throughput **1.58x** and the **v2-mini** model increase the mean throughput **4.18x**. +The bulk size was set to 8. Compared with the v1 model, the **v2-distill** model provided a **1.58x increase in mean throughput** and the **v2-mini** model provided a **4.18x increase in mean throughput**. ### Search -In this experiments, we ingest 1 million documents into the index, and use 20 clients to search in concurrent. We record the search client-side P99 latency and model inference P99 latency. We test the search performance for the **bi-encoder** mode. +In these experiments, we ingested 1 million documents into an index and used 20 clients to perform concurrent searches. We recorded the p99 for both client-side search and model inference. We tested search performance for the **bi-encoder** mode. #### Remote deployment using GPU -Compared with the v1 model, the **v2-distill** model decrease the search client-side latency by **11.7%** and model inference latency by **23%**. +Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 11.7% and model inference latency by 23%**. #### Local deployment using CPU -Compared with the v1 model, the **v2-distill** model decrease the search client-side latency by **30.2%** and model inference latency by **33.3%**. +Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 30.2% and model inference latency by 33.3%**. -## Search Relevance Benchmark - -Consistent with our previous [blog](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we benchmark the model search relevance on subset of BEIR benchmark. The detailed search relevance is shown in the table below. All v2-series models outperform the v1 model with the same architecture. +## Search relevance benchmarks -

+Similar to the tests described in our previous [blog post](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we evaluated model search relevance on a subset of the BEIR benchmark. The search relevance results are provided in the following table. **All v2-series models outperform the v1 models with the same architecture**, indicating that distillation from a heterogeneous teacher model is a more effective method than original pretraining using InfoNCE loss. | Model | Average | Trec Covid | NFCorpus | NQ | HotpotQA | FiQA | ArguAna | Touche | DBPedia | SCIDOCS | FEVER | Climate FEVER | SciFact | Quora | |-------|---------|------------|----------|----|----------|------|---------|--------|---------|---------|-------|---------------|---------|-------| @@ -106,58 +104,76 @@ Consistent with our previous [blog](https://opensearch.org/blog/improving-docume | [opensearch-neural-sparse-encoding-doc-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-distill) | 0.504 | 0.690 | 0.343 | 0.528 | 0.675 | 0.357 | 0.496 | 0.287 | 0.418 | 0.166 | 0.818 | 0.224 | 0.715 | 0.841 | | [opensearch-neural-sparse-encoding-doc-v2-mini](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-mini) | 0.497 | 0.709 | 0.336 | 0.510 | 0.666 | 0.338 | 0.480 | 0.285 | 0.407 | 0.164 | 0.812 | 0.216 | 0.699 | 0.837 | -
+## Registering and deploying v2 models + +OpenSearch now provides [pretrained v2 sparse encoding models](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models). Depending on the search mode, you need to register different models: + +- In **doc-only mode**, you need to register a sparse encoding model for ingestion and a tokenizer for search. +- In **bi-encoder mode**, you need to register a sparse encoding model that will be used for ingestion and search. + +For detailed setup steps and tutorials, see [Neural sparse search](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). + +### Registering and deploying models in doc-only mode -## Register and Deploy V2 Models +To register and deploy models in doc-only mode, use the following steps. -The v2 series sparse encoding models can be registered as OpenSearch-provided pretrained models supported by ml-commons plugin. The register APIs are listed as follows. +1. Register and deploy a sparse encoding model for ingestion: -For ingestion and search with sparse model deployed, please check the [documentation](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). + ```json + POST /_plugins/_ml/models/_register?deploy=true + { + "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v2-distill", + "version": "1.0.0", + "model_format": "TORCH_SCRIPT" + } + ``` -### Register&Deploy models of doc-only mode +1. Register and deploy a tokenizer for search: -```json -## register sparse_encoding model for ingestion -POST /_plugins/_ml/models/_register?deploy=true -{ - "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-doc-v2-distill", - "version": "1.0.0", - "model_format": "TORCH_SCRIPT" -} + ``` + POST /_plugins/_ml/models/_register?deploy=true + { + "name": "amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1", + "version": "1.0.1", + "model_format": "TORCH_SCRIPT" + } + ``` -## register sparse_tokenize model for search -POST /_plugins/_ml/models/_register?deploy=true -{ - "name": "amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1", - "version": "1.0.1", - "model_format": "TORCH_SCRIPT" -} +1. Get model IDs for the model and tokenizer by calling the Tasks API: -## get model_id from task_ids returned by register model API -GET /_plugins/_ml/tasks/{task_id} -``` + ``` + GET /_plugins/_ml/tasks/{task_id} + ``` -### Register&Deploy models of bi-encoder mode +### Registering and deploying models in bi-encoder mode -```json -## register sparse_encoding model for ingestion and search -POST /_plugins/_ml/models/_register?deploy=true -{ - "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill", - "version": "1.0.0", - "model_format": "TORCH_SCRIPT" -} +To register and deploy models in bi-encoder mode, use the following steps. -## get model_id from task_ids returned by register model API -GET /_plugins/_ml/tasks/{task_id} -``` +1. Register and deploy a sparse encoding model for ingestion and search: + + ```json + POST /_plugins/_ml/models/_register?deploy=true + { + "name": "amazon/neural-sparse/opensearch-neural-sparse-encoding-v2-distill", + "version": "1.0.0", + "model_format": "TORCH_SCRIPT" + } + ``` + +1. Get the model ID for the sparse encoding model by calling the Tasks API: + + ``` + GET /_plugins/_ml/tasks/{task_id} + ``` ## Further reading -Read more about neural sparse search: +For more information about neural sparse search, see our other blog posts: -1. [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) -1. [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) -1. [Introducing the neural sparse two-phase algorithm]({{site.baseurl}}/blog/Introducing-a-neural-sparse-two-phase-algorithm) +- [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) +- [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) +- [Introducing the neural sparse two-phase algorithm]({{site.baseurl}}/blog/Introducing-a-neural-sparse-two-phase-algorithm) + +--- -[^1]: We pick a subset of [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data) collected by sentence-transformers. All datasets overlapped with BEIR are excluded to keep a zero-shot setting for the evaluation. \ No newline at end of file +[^1]: For pretraining, we selected a portion of the sentence transformers [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data). We removed any data that also appeared in BEIR to maintain a zero-shot evaluation environment. \ No newline at end of file From fea60efd11872dd47199997ecadd1780932c8c6b Mon Sep 17 00:00:00 2001 From: Fanit Kolchina Date: Fri, 16 Aug 2024 17:11:53 -0400 Subject: [PATCH 4/9] Correct dataset name Signed-off-by: Fanit Kolchina --- _posts/2024-08-19-neural-sparse-v2-models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 41009923f4..44d57f21a2 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -96,7 +96,7 @@ Compared with the v1 model, the **v2-distill** model **decreased client-side sea Similar to the tests described in our previous [blog post](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we evaluated model search relevance on a subset of the BEIR benchmark. The search relevance results are provided in the following table. **All v2-series models outperform the v1 models with the same architecture**, indicating that distillation from a heterogeneous teacher model is a more effective method than original pretraining using InfoNCE loss. -| Model | Average | Trec Covid | NFCorpus | NQ | HotpotQA | FiQA | ArguAna | Touche | DBPedia | SCIDOCS | FEVER | Climate FEVER | SciFact | Quora | +| Model | Average | Trec-Covid | NFCorpus | NQ | HotpotQA | FiQA | ArguAna | Touche | DBPedia | SciDocs | FEVER | Climate FEVER | SciFact | Quora | |-------|---------|------------|----------|----|----------|------|---------|--------|---------|---------|-------|---------------|---------|-------| | [opensearch-neural-sparse-encoding-v1](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v1) | 0.524 | 0.771 | 0.360 | 0.553 | 0.697 | 0.376 | 0.508 | 0.278 | 0.447 | 0.164 | 0.821 | 0.263 | 0.723 | 0.856 | | [opensearch-neural-sparse-encoding-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-v2-distill) | 0.528 | 0.775 | 0.347 | 0.561 | 0.685 | 0.374 | 0.551 | 0.278 | 0.435 | 0.173 | 0.849 | 0.249 | 0.722 | 0.863 | From 320137764f4d4bbd3fa61c76daee26d57a5472a6 Mon Sep 17 00:00:00 2001 From: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:07:42 -0400 Subject: [PATCH 5/9] Apply suggestions from code review Co-authored-by: Nathan Bower Signed-off-by: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> --- _posts/2024-08-19-neural-sparse-v2-models.md | 45 ++++++++++---------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 44d57f21a2..7b602592b9 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -21,10 +21,10 @@ featured_image: false # /assets/media/blog-images/__example__image__name.jpg Neural sparse search is a novel and efficient method for semantic retrieval, [introduced in OpenSearch 2.11](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/). Sparse encoding models encode text into (token, weight) entries, allowing OpenSearch to build indexes and perform searches using Lucene's inverted index. Neural sparse search is efficient and generalizes well in out-of-domain (OOD) scenarios. We are excited to announce the release of our v2 series neural sparse models: -- **v2-distill model**: This model **reduces model parameters by 50%**, resulting in lower memory requirements and costs. It **increases ingestion throughput by 1.39 on GPU and 1.74x on CPU**. The v2-distill architecture supports both doc-only and bi-encoder modes. -- **v2-mini model**: This model **reduces model parameters by 75%**, also reducing memory requirements and costs. It **increases ingestion throughput by 1.74x on GPU and 4.18x on CPU**. The v2-mini architecture supports the doc-only mode. +- **v2-distill model**: This model **reduces model parameters by 50%**, resulting in lower memory requirements and costs. It **increases ingestion throughput by 1.39 on GPU and 1.74x on CPU**. The v2-distill architecture supports both the doc-only and bi-encoder modes. +- **v2-mini model**: This model **reduces model parameters by 75%**, also reducing memory requirements and costs. It **increases ingestion throughput by 1.74x on GPUs and 4.18x on CPUs**. The v2-mini architecture supports the doc-only mode. -Additionally, all v2 models achieve **better search relevance**. A comparison with v1 models is shown in the following table. All v2 models are now available on both [OpenSearch](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models) and [Hugging Face](https://huggingface.co/opensearch-project). +Additionally, all v2 models achieve **better search relevance**. The following table compares search relevance between the v1 and v2 models. All v2 models are now available in both [OpenSearch](https://opensearch.org/docs/latest/ml-commons-plugin/pretrained-models/#sparse-encoding-models) and [Hugging Face](https://huggingface.co/opensearch-project). | Model | Requires no inference for retrieval | Model parameters | AVG NDCG@10 | |-------|------------------------------|------------------|-------------| @@ -34,13 +34,13 @@ Additionally, all v2 models achieve **better search relevance**. A comparison wi | [opensearch-neural-sparse-encoding-doc-v2-distill](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-distill) | ✔️ | 67M | 0.504 | | [opensearch-neural-sparse-encoding-doc-v2-mini](https://huggingface.co/opensearch-project/opensearch-neural-sparse-encoding-doc-v2-mini) | ✔️ | 23M | 0.497 | -## From v1 series to v2 series models +## From v1 to v2 series models The transition from v1 to v2 models in OpenSearch represents a significant advancement in neural sparse search capabilities. ### Limitations of v1 models -For neural sparse search, the sparse encoding model is critical as it influences document scoring and ranking, directly impacting search relevance. The model’s inference speed also affects ingestion throughput and client-side search latency in bi-encoder mode. When we released neural sparse search in OpenSearch, we also launched two neural sparse models supporting doc-only and bi-encoder modes, respectively. +For neural sparse search, the sparse encoding model is critical because it influences document scoring and ranking, directly impacting search relevance. The model's inference speed also affects ingestion throughput and client-side search latency in bi-encoder mode. When we released neural sparse search in OpenSearch, we also launched two neural sparse models supporting doc-only and bi-encoder mode, respectively. The primary challenge for v1 models is their large size. The v1 series models are based on the BERT base model, a 12-layer transformer with 133 million parameters. Compared to popular dense embedding models like [`tas-b`](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b) and [`all-MiniLM-L6-v2`](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2), the inference cost of the v1 models is 2x to 4x higher. Therefore, reducing model parameters without compromising search accuracy became essential for the v2 series. @@ -48,53 +48,54 @@ The primary challenge for v1 models is their large size. The v1 series models ar In neural models, performance is closely tied to the number of parameters. When using a smaller architecture, the training algorithm must be enhanced to offset any performance drop. For retrieval tasks, common techniques include **pretraining** and **knowledge distillation**: -- **Pretraining**: This involves training models on large datasets, often constructed using specific rules. Examples of such dataset elements are `(title, body)` pairs in news articles or `(question, answer)` pairs on Q&A websites. Pretraining enhances the model’s search relevance and ability to generalize. +- **Pretraining**: This involves training models on large datasets often constructed using specific rules. Examples of such dataset elements are `(title, body)` pairs in news articles or `(question, answer)` pairs on Q&A websites. Pretraining enhances the model's search relevance and ability to generalize. - **Knowledge distillation**: Some models are powerful but suffer from inefficiencies because of their large size or complex structure. An example of such a model is the cross-encoder reranker. Distillation transfers knowledge from these teacher models to smaller ones, preserving high performance while eliminating these drawbacks. -Dense retrievers are usually pretrained using Information Noise-Contrastive Estimation (InfoNCE) loss, which improves consistency and uniformity of dense representations. However, we found that InfoNCE loss does not enhance sparse embeddings in doc-only mode as it does for dense models. Instead, knowledge distillation loss is a more effective optimization technique for sparse encoding models. Finding a suitable teacher model for large-scale pretraining is challenging. Siamese encoders are generally not strong models, while cross-encoders struggle with handling large pretraining datasets. Inspired by the performance boost from the [hybrid search of dense and lexical (sparse) approaches](https://opensearch.org/blog/hybrid-search/), we decided to combine a bi-encoder sparse retriever with Siamese dense models to create a strong teacher model. This model combines the strengths of heterogeneous retrievers and is efficient enough for pretraining. We plan to publish a paper detailing the training procedure. +Dense retrievers are usually pretrained using Information Noise-Contrastive Estimation (InfoNCE) loss, which improves consistency and uniformity of dense representations. However, we found that InfoNCE loss does not enhance sparse embeddings in doc-only mode as it does for dense models. Instead, knowledge distillation loss is a more effective optimization technique for sparse encoding models. Finding a suitable teacher model for large-scale pretraining is challenging. Siamese encoders are generally not strong models, while cross-encoders struggle with handling large pretraining datasets. Inspired by the performance boost demonstrated by dense and lexical (sparse) [hybrid search](https://opensearch.org/blog/hybrid-search/), we decided to combine a bi-encoder sparse retriever with Siamese dense models to create a strong teacher model. This model combines the strengths of heterogeneous retrievers and is efficient enough for pretraining. We plan to publish a paper detailing the training procedure. -Pretraining with knowledge distillation allows us to reduce the number of model parameters without compromising performance. Because we performed pretraining on a massive corpus[^1], the **v2 series models** achieved **improved search relevance** while significantly **reducing the number of model parameters**. We have released distill-BERT-based models for both doc-only and bi-encoder modes (similar in size to [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b)) and a miniLM-based model for the doc-only mode (similar in size to [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)). +Pretraining with knowledge distillation allows you to reduce the number of model parameters without compromising performance. Because we performed pretraining on a massive corpus[^1], the **v2 series models** achieved **improved search relevance** while significantly **reducing the number of model parameters**. We have released distill-BERT-based models for both the doc-only and bi-encoder modes (similar in size to [tas-b](https://huggingface.co/sentence-transformers/msmarco-distilbert-base-tas-b)) and a miniLM-based model for the doc-only mode (similar in size to [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)). ## Accelerating model inference -The v2 models continue to use the transformer architecture, reducing the number of parameters by decreasing the number of layers and the hidden dimension size. As a result, the smaller v2 models offer higher ingestion throughput and lower search latency. We benchmarked the v2 models in ingestion and search scenarios using the MS MARCO passage retrieval dataset on an OpenSearch 2.16 cluster with three nodes running on r7a.8xlarge EC2 instances. +The v2 models continue to use the transformer architecture, reducing the number of parameters by decreasing the number of layers and the hidden dimension size. As a result, the smaller v2 models offer higher ingestion throughput and lower search latency. We benchmarked the v2 models in ingestion and search scenarios using the MS MARCO passage retrieval dataset on an OpenSearch 2.16 cluster with three nodes running on r7a.8xlarge Amazon Elastic Compute Cloud (Amazon EC2) instances. -**GPU deployment**: We used a SageMaker GPU endpoint to host the neural sparse model, connecting to it using a remote connector. For complete deployment code, see [this example](https://github.com/zhichao-aws/neural-search/blob/neural_sparse_sagemaker/neural_sparse_sagemaker_example/run.ipynb). The model was hosted on a **g5.xlarge** GPU instance. +**GPU deployment**: We used an Amazon SageMaker GPU endpoint to host the neural sparse model, connecting to it using a remote connector. For the complete deployment code, see [this example](https://github.com/zhichao-aws/neural-search/blob/neural_sparse_sagemaker/neural_sparse_sagemaker_example/run.ipynb). The model was hosted on a **g5.xlarge** GPU instance. **CPU deployment**: The model was deployed on **all three nodes** in the cluster. + In these experiments, we set the `batch_size` of the `sparse_encoding` ingestion processor to `2`. We recorded the mean ingestion throughput and the p99 client-side latency for the Bulk API, using 20 clients for ingestion. #### Remote deployment using GPU -The bulk size was set to 24. The experiment results are listed in the following figure. Compared with the v1 model, the **v2-distill** model provided a **1.39x increase in mean throughput** and the **v2-mini** model provided a **1.74x increase in mean throughput**. +The bulk size was set to 24. The experiment results are presented in the following figure. Compared with the v1 model, the **v2-distill** model provided a **1.39x increase in mean throughput**, and the **v2-mini** model provided a **1.74x increase in mean throughput**. -#### Local deployment using CPU +#### Local deployment on a CPU -The bulk size was set to 8. Compared with the v1 model, the **v2-distill** model provided a **1.58x increase in mean throughput** and the **v2-mini** model provided a **4.18x increase in mean throughput**. +The bulk size was set to 8. Compared with the v1 model, the **v2-distill** model provided a **1.58x increase in mean throughput**, and the **v2-mini** model provided a **4.18x increase in mean throughput**, as shown in the following figure. ### Search -In these experiments, we ingested 1 million documents into an index and used 20 clients to perform concurrent searches. We recorded the p99 for both client-side search and model inference. We tested search performance for the **bi-encoder** mode. +In these experiments, we ingested 1 million documents into an index and used 20 clients to perform concurrent searches. We recorded the p99 latency for both client-side search and model inference. We tested search performance for the **bi-encoder** mode. #### Remote deployment using GPU -Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 11.7% and model inference latency by 23%**. +Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 11.7% and model inference latency by 23%**, as shown in the following figure. -#### Local deployment using CPU +#### Local deployment on a CPU -Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 30.2% and model inference latency by 33.3%**. +Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 30.2% and model inference latency by 33.3%**, as shown in the following figure. ## Search relevance benchmarks -Similar to the tests described in our previous [blog post](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we evaluated model search relevance on a subset of the BEIR benchmark. The search relevance results are provided in the following table. **All v2-series models outperform the v1 models with the same architecture**, indicating that distillation from a heterogeneous teacher model is a more effective method than original pretraining using InfoNCE loss. +Similarly to the tests described in our previous [blog post](https://opensearch.org/blog/improving-document-retrieval-with-sparse-semantic-encoders/), we evaluated model search relevance on a subset of the BEIR benchmark. The search relevance results are provided in the following table. **All v2-series models outperform the v1 models with the same architecture**, indicating that distillation from a heterogeneous teacher model is a more effective method than pretraining using InfoNCE loss. | Model | Average | Trec-Covid | NFCorpus | NQ | HotpotQA | FiQA | ArguAna | Touche | DBPedia | SciDocs | FEVER | Climate FEVER | SciFact | Quora | |-------|---------|------------|----------|----|----------|------|---------|--------|---------|---------|-------|---------------|---------|-------| @@ -111,7 +112,7 @@ OpenSearch now provides [pretrained v2 sparse encoding models](https://opensearc - In **doc-only mode**, you need to register a sparse encoding model for ingestion and a tokenizer for search. - In **bi-encoder mode**, you need to register a sparse encoding model that will be used for ingestion and search. -For detailed setup steps and tutorials, see [Neural sparse search](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). +For detailed setup instructions and tutorials, see [Neural sparse search](https://opensearch.org/docs/latest/search-plugins/neural-sparse-search/). ### Registering and deploying models in doc-only mode @@ -130,7 +131,7 @@ To register and deploy models in doc-only mode, use the following steps. 1. Register and deploy a tokenizer for search: - ``` + ```json POST /_plugins/_ml/models/_register?deploy=true { "name": "amazon/neural-sparse/opensearch-neural-sparse-tokenizer-v1", @@ -168,7 +169,7 @@ To register and deploy models in bi-encoder mode, use the following steps. ## Further reading -For more information about neural sparse search, see our other blog posts: +For more information about neural sparse search, see these previous blog posts: - [Improving document retrieval with sparse semantic encoders]({{site.baseurl}}/blog/improving-document-retrieval-with-sparse-semantic-encoders) - [A deep dive into faster semantic sparse retrieval in OpenSearch 2.12]({{site.baseurl}}/blog/A-deep-dive-into-faster-semantic-sparse-retrieval-in-OS-2.12) @@ -176,4 +177,4 @@ For more information about neural sparse search, see our other blog posts: --- -[^1]: For pretraining, we selected a portion of the sentence transformers [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data). We removed any data that also appeared in BEIR to maintain a zero-shot evaluation environment. \ No newline at end of file +[^1]: For pretraining, we selected a portion of the sentence transformer [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data). We removed any data that also appeared in BEIR in order to maintain a zero-shot evaluation environment. \ No newline at end of file From 4930c27f7561635baf3cda01b500cbbb047e0280 Mon Sep 17 00:00:00 2001 From: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:08:47 -0400 Subject: [PATCH 6/9] Update _posts/2024-08-19-neural-sparse-v2-models.md Signed-off-by: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> --- _posts/2024-08-19-neural-sparse-v2-models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 7b602592b9..50a69ca46f 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -65,7 +65,7 @@ The v2 models continue to use the transformer architecture, reducing the number In these experiments, we set the `batch_size` of the `sparse_encoding` ingestion processor to `2`. We recorded the mean ingestion throughput and the p99 client-side latency for the Bulk API, using 20 clients for ingestion. -#### Remote deployment using GPU +#### Remote deployment on a GPU The bulk size was set to 24. The experiment results are presented in the following figure. Compared with the v1 model, the **v2-distill** model provided a **1.39x increase in mean throughput**, and the **v2-mini** model provided a **1.74x increase in mean throughput**. From e5f0f09dc8f027fb2c6556c71351b003513d6c0f Mon Sep 17 00:00:00 2001 From: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:09:18 -0400 Subject: [PATCH 7/9] Apply suggestions from code review Signed-off-by: kolchfa-aws <105444904+kolchfa-aws@users.noreply.github.com> --- _posts/2024-08-19-neural-sparse-v2-models.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 50a69ca46f..fa43a16509 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -81,7 +81,7 @@ The bulk size was set to 8. Compared with the v1 model, the **v2-distill** model In these experiments, we ingested 1 million documents into an index and used 20 clients to perform concurrent searches. We recorded the p99 latency for both client-side search and model inference. We tested search performance for the **bi-encoder** mode. -#### Remote deployment using GPU +#### Remote deployment on a GPU Compared with the v1 model, the **v2-distill** model **decreased client-side search latency by 11.7% and model inference latency by 23%**, as shown in the following figure. From 4ad4073d1f7e67fd9067cfa9c3c6928641404755 Mon Sep 17 00:00:00 2001 From: Fanit Kolchina Date: Tue, 20 Aug 2024 18:14:29 -0400 Subject: [PATCH 8/9] Added meta keywords and changed date Signed-off-by: Fanit Kolchina --- _posts/2024-08-19-neural-sparse-v2-models.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index fa43a16509..03aa58f4fc 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -7,14 +7,13 @@ authors: - yych - dylantong - kolchfa -date: 2024-08-19 +date: 2024-08-21 categories: - technical-posts has_science_table: true -meta_keywords: OpenSearch semantic search, neural sparse search, semantic sparse retrieval +meta_keywords: neural sparse models, OpenSearch semantic search, semantic sparse retrieval, neural search meta_description: Accelerating inference and improving search with v2 neural sparse encoding models - -excerpt: We're excited to introduce the neural sparse v2 series models---a significant upgrade that enhances performance across key metrics. Our benchmarks reveal improved ingestion speed, faster search performance, and better search relevance. +excerpt: OpenSearch announces the availability of v2 series neural sparse models that enhance the efficiency of semantic sparse retrieval while accelerating inference and improving search. featured_blog_post: true featured_image: false # /assets/media/blog-images/__example__image__name.jpg --- From 570886d036e7c737553c87aae84eccc244bcc3d5 Mon Sep 17 00:00:00 2001 From: Kris Freedain Date: Wed, 21 Aug 2024 13:01:58 -0700 Subject: [PATCH 9/9] Update 2024-08-19-neural-sparse-v2-models.md setting "featured_blog_post: false" while we continue to promote OpenSearchCon Signed-off-by: Kris Freedain --- _posts/2024-08-19-neural-sparse-v2-models.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2024-08-19-neural-sparse-v2-models.md b/_posts/2024-08-19-neural-sparse-v2-models.md index 03aa58f4fc..eb27cab684 100644 --- a/_posts/2024-08-19-neural-sparse-v2-models.md +++ b/_posts/2024-08-19-neural-sparse-v2-models.md @@ -14,7 +14,7 @@ has_science_table: true meta_keywords: neural sparse models, OpenSearch semantic search, semantic sparse retrieval, neural search meta_description: Accelerating inference and improving search with v2 neural sparse encoding models excerpt: OpenSearch announces the availability of v2 series neural sparse models that enhance the efficiency of semantic sparse retrieval while accelerating inference and improving search. -featured_blog_post: true +featured_blog_post: false featured_image: false # /assets/media/blog-images/__example__image__name.jpg --- @@ -176,4 +176,4 @@ For more information about neural sparse search, see these previous blog posts: --- -[^1]: For pretraining, we selected a portion of the sentence transformer [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data). We removed any data that also appeared in BEIR in order to maintain a zero-shot evaluation environment. \ No newline at end of file +[^1]: For pretraining, we selected a portion of the sentence transformer [training data](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2#training-data). We removed any data that also appeared in BEIR in order to maintain a zero-shot evaluation environment.