diff --git a/zh/_blog.yml b/zh/_blog.yml index d2ce2396a6..452951c253 100644 --- a/zh/_blog.yml +++ b/zh/_blog.yml @@ -1428,7 +1428,7 @@ - training - local: quanto-introduction - title: "Quanto:PyTorch 量化工具包" + title: Quanto:PyTorch 量化工具包 author: dacorvo thumbnail: /blog/assets/169_quanto_intro/thumbnail.png date: March 18, 2024 @@ -1438,6 +1438,29 @@ - transformers - diffusers +- local: phi2-intel-meteor-lake + title: 笔记本电脑上的聊天机器人:在英特尔 Meteor Lake 上运行 Phi-2 + author: juliensimon + thumbnail: /blog/assets/phi2-intel-meteor-lake/02.jpg + date: March 20, 2024 + tags: + - partnerships + - intel + - llm + +- local: embedding-quantization + title: 用于显著提高检索速度和降低成本的二进制和标量嵌入量化 + author: aamirshakir + guest: true + thumbnail: /blog/assets/embedding-quantization/thumbnail.png + date: Mar 22, 2024 + tags: + - nlp + - community + - guide + - collaboration + - research + - local: cloudflare-workers-ai title: 为 Hugging Face 用户带来无服务器 GPU 推理服务 author: philschmid @@ -1448,3 +1471,13 @@ - cloudflare - llm - inference + +- local: google-cloud-model-garden + title: 在 Google Cloud 上轻松部署开放大语言模型 + author: philschmid + thumbnail: /blog/assets/173_gcp-partnership/thumbnail.jpg + date: April 10, 2024 + tags: + - partnerships + - gcp + - hardware \ No newline at end of file diff --git a/zh/embedding-quantization.md b/zh/embedding-quantization.md new file mode 100644 index 0000000000..5452321634 --- /dev/null +++ b/zh/embedding-quantization.md @@ -0,0 +1,387 @@ +--- +title: "用于显著提高检索速度和降低成本的二进制和标量嵌入量化" +thumbnail: /blog/assets/embedding-quantization/thumbnail.png +authors: +- user: aamirshakir + guest: true +- user: tomaarsen +- user: SeanLee97 + guest: true +translators: +- user: innovation64 +- user: zhongdongy + proofreader: true +--- + +# 用于显著提高检索速度和降低成本的二进制和标量嵌入量化 + +我们引入了嵌入量化的概念,并展示了它们对检索速度、内存使用、磁盘空间和成本的影响。我们将讨论理论上和实践中如何对嵌入进行量化,然后介绍一个 [演示](https://huggingface.co/spaces/sentence-transformers/quantized-retrieval),展示了 4100 万维基百科文本的真实检索场景。 + +## 目录 + +* [为什么使用嵌入?](#为什么使用嵌入?) + + [嵌入可能难以扩展](#嵌入可能难以扩展) +* [提高可扩展性](#提高可扩展性) + + [二进制量化](#二进制量化) + - [Sentence Transformers 中的二进制量化](#sentence-transformers-中的二进制量化) + - [向量数据库中的二进制量化](#向量数据库中的二进制量化) + + [标量(int8)量化](#标量_int8_量化 +) + - [Sentence Transformers 中的标量量化](#sentence-transformers-中的标量量化) + - [向量数据库中的标量量化](#向量数据库中的标量量化) + + [结合二进制和标量量化](#结合二进制和标量量化) + + [量化实验](#量化实验) + + [重打分的影响](#重打分的影响) + - [二进制重打分](#二进制重打分) + - [标量(Int8)重打分](#标量-Int8-重打分) + - [检索速度](#检索速度) + + [性能汇总](#性能汇总) + + [演示](#演示) + + [自己尝试](#自己尝试) + + [未来工作](#未来工作) + + [致谢](#致谢) + + [引用](#引用) + + [参考文献](#参考文献) + +## 为什么使用嵌入? + +嵌入是自然语言处理中最多样化的工具之一,支持各种设置和使用场景。本质上,嵌入是对更复杂对象 (如文本、图像、音频等) 的数值表示。具体来说,这些对象被表示为 n 维向量。 + +在转换了复杂对象之后,你可以通过计算相应嵌入的相似性来确定它们的相似性!这对于许多使用场景至关重要: 它为推荐系统、检索、单次学习或少样本学习、异常检测、相似性搜索、释义检测、聚类、分类等提供了基础。 + +### 嵌入可能难以扩展 + +但是,当我们在实际应用中使用嵌入时,可能会遇到一些问题。比如,现在很多先进的模型产生的嵌入都是 1024 维的,每个维度需要 4 字节的空间来存储 (float 32 编码)。如果你要处理 2.5 亿个这样的向量,那就需要大约 1TB 的内存,这既花钱又可能导致处理速度变慢。 + +下表展示了一些不同的模型,它们的维度大小、需要的内存量以及相应的成本。成本是按照 AWS 上一种叫做 x2gd 的实例来估算的,大概每个月每 GB 需要 3.8 美元。 + +| 嵌入维数| 模型样例 | 100M 嵌入 | 250M 嵌入 | 1B 嵌入 | +|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|-----------------|-------------------------| +| 384 | [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)
[bge-small-en-v1.5](https://huggingface.co/BAAI/bge-small-en-v1.5) | 143.05GB
$543 / mo | 357.62GB
$1,358 / mo | 1430.51GB
$5,435 / mo | +| 768 | [all-mpnet-base-v2](https://huggingface.co/sentence-transformers/all-mpnet-base-v2)
[bge-base-en-v1.5](https://huggingface.co/BAAI/bge-base-en-v1.5)
[jina-embeddings-v2-base-en](https://huggingface.co/jinaai/jina-embeddings-v2-base-en)
[nomic-embed-text-v1](https://huggingface.co/nomic-ai/nomic-embed-text-v1) |286.10GB
$1,087 / mo|715.26GB
$2,717 / mo|2861.02GB
$10,871 / mo| +| 1024 | [bge-large-en-v1.5](https://huggingface.co/BAAI/bge-large-en-v1.5)
[mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1)
[Cohere-embed-english-v3.0](https://txt.cohere.com/introducing-embed-v3/) |381.46GB
$1,449 / mo|953.67GB
$3,623 / mo|3814.69GB
$14,495 / mo| +| 1536 | [OpenAI text-embedding-3-small](https://openai.com/blog/new-embedding-models-and-api-updates) |572.20GB
$2,174 / mo|1430.51GB
$5,435 / mo|5722.04GB
$21,743 / mo| +| 3072 | [OpenAI text-embedding-3-large](https://openai.com/blog/new-embedding-models-and-api-updates) |1144.40GB
$4,348 / mo|2861.02GB
$10,871 / mo|11444.09GB
$43,487 / mo| + +## 提高可扩展性 + +有几种方法可以应对嵌入扩展的挑战。最常见的方法是降维,比如使用 [主成分分析 (PCA)](https://en.wikipedia.org/wiki/Principal_component_analysis)。然而,传统的降维方法——比如 PCA ——在处理嵌入时往往效果不佳。 +最近,有关于 [ Matryoshka 表征学习](https://arxiv.org/abs/2205.13147) (MRL) 的新闻 ([博客](https://huggingface.co/blog/matryoshka)),这种方法由 [OpenAI](https://openai.com/blog/new-embedding-models-and-api-updates) 使用,允许更经济的嵌入。使用 MRL 时,只使用前 `n` 个嵌入维度。这种方法已经被一些开源模型采用,比如 [nomic-ai/nomic-embed-text-v1.5](https://huggingface.co/nomic-ai/nomic-embed-text-v1.5) 和 [mixedbread-ai/mxbai-embed-2d-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-2d-large-v1)。对于 OpenAI 的 `text-embedding-3-large` 模型,我们看到在 12 倍压缩下性能保留了 93.1 %,而对于 nomic 的模型,在 3 倍压缩下保留了 95.8% 的性能,在 6 倍压缩下保留了 90% 的性能。 + +然而,还有一种新的方法可以在这个挑战上取得进展; 它不涉及降维,而是减少嵌入中每个个体值的尺寸大小: **量化**。我们的量化实验将展示,我们可以在显著加快计算速度并节省内存、存储和成本的同时,保持大量的性能。让我们进一步了解一下吧! + +### 二进制量化 + +与在模型中减少权重精度的量化不同,嵌入的量化是指对嵌入本身进行的一个后处理步骤。特别是,二进制量化指的是将嵌入中的 `float32` 值转换为 1 bit ,从而在内存和存储使用上实现 32 倍的减少。 + +要将 `float32` 嵌入量化为二进制,我们只需将归一化的嵌入在 0 处进行阈值处理: + +$$ + f(x)= +\begin{cases} + 0 & \text{如果 } x\leq 0\\ + 1 & \text{如果 } x \gt 0 +\end{cases} +$$ + +我们可以使用汉明距离来高效地检索这些二进制嵌入。汉明距离是指两个二进制嵌入在位上不同的位置数量。汉明距离越低,嵌入越接近; 因此,文档的相关性越高。汉明距离的一个巨大优势是它可以用 2 个 CPU 周期轻松计算,允许极快的性能。 + +[Yamada 等人 (2021)](https://arxiv.org/abs/2106.00882) 引入了一个重打分步骤,他们称之为 _rerank_ ,以提高性能。他们提议可以使用点积将 `float32` 查询嵌入与二进制文档嵌入进行比较。在实践中,我们首先使用二进制查询嵌入和二进制文档嵌入检索 `rescore_multiplier * top_k` 的结果——即双二进制检索的前 k 个结果的列表——然后使用 `float32` 查询嵌入对这个二进制文档嵌入列表进行重打分。 + +通过应用这种新颖的重打分步骤,我们能够在减少内存和磁盘空间使用 32 倍的同时,保留高达 ~96% 的总检索性能,并使检索速度提高多达 32 倍。如果没有重打分,我们能够保留大约 ~92.5% 的总检索性能。 + +#### Sentence Transformers 中的二进制量化 + +将一个维度为 1024 的嵌入量化为二进制将得到 1024 比特。实际上,将比特存储为字节要常见得多,因此当我们量化为二进制嵌入时,我们使用 `np.packbits` 将比特打包成字节。 + +因此,将一个维度为 1024 的 `float32` 嵌入量化后,得到一个维度为 128 的 `int8` 或 `uint8` 嵌入。下面是两种使用 [Sentence Transformers](https://sbert.net/) 生成量化嵌入的方法: + +```python +from sentence_transformers import SentenceTransformer + +# 1. Load an embedding model +model = SentenceTransformer("mixedbread-ai/mxbai-embed-large-v1") + +# 2a. Encode some text using "binary" quantization +binary_embeddings = model.encode( + ["I am driving to the lake.", "It is a beautiful day."], + precision="binary", +) +``` + +或者 + +```python +from sentence_transformers import SentenceTransformer +from sentence_transformers.quantization import quantize_embeddings + +# 1. Load an embedding model +model = SentenceTransformer("mixedbread-ai/mxbai-embed-large-v1") + +# 2b. or, encode some text without quantization & apply quantization afterwards +embeddings = model.encode(["I am driving to the lake.", "It is a beautiful day."]) +binary_embeddings = quantize_embeddings(embeddings, precision="binary") +``` + +**参考:** + +mixedbread-ai/mxbai-embed-large-v1SentenceTransformer.encodequantize_embeddings + +在这里,你可以看到默认的 `float32` 嵌入和二进制嵌入在形状、大小和 `numpy` 数据类型方面的差异: + +```python +>>> embeddings.shape +(2, 1024) +>>> embeddings.nbytes +8192 +>>> embeddings.dtype +float32 +>>> binary_embeddings.shape +(2, 128) +>>> binary_embeddings.nbytes +256 +>>> binary_embeddings.dtype +int8 +``` + +请注意,你还可以选择 `"ubinary"` 来使用无符号的 `uint8` 数据格式将嵌入量化为二进制。这可能取决于你的向量库/数据库的要求。 + +#### 向量数据库中的二进制量化 + +| 向量数据库 | 是否支持 | +| --- | --- | +| Faiss | [是](https://github.com/facebookresearch/faiss/wiki/Binary-indexes) | +| USearch | [是](https://github.com/unum-cloud/usearch) | +| Vespa AI | [是](https://docs.vespa.ai/en/reference/schema-reference.html) | +| Milvus | [是](https://milvus.io/docs/index.md) |通过 +| Qdrant | [二进制量化](https://qdrant.tech/documentation/guides/quantization/#binary-quantization) |通过 +| Weaviate | [二进制量化](https://weaviate.io/developers/weaviate/configuration/bq-compression) | + +### 标量 (int8) 量化 + +我们使用标量量化过程将 `float32` 嵌入转换为 `int8` 。这涉及到将 `float32` 值的连续范围映射到可以表示 256 个不同级别 (从 -128 到 127) 的 `int8` 值的离散集合,如下面的图像所示。这是通过使用大量的嵌入校准数据集来完成的。我们计算这些嵌入的范围,即每个嵌入维度的 `min` 和 `max` 。从这里,我们计算将每个值分类的步骤 (桶)。 + +为了进一步提高检索性能,你可以可选地应用与二进制嵌入相同的重打分步骤。重要的是要注意,校准数据集极大地影响性能,因为它定义了量化桶。 + +

+ + Source: https://qdrant.tech/articles/scalar-quantization/ +

+ +通过将标量量化为 `int8` ,我们将原始 `float32` 嵌入的精度降低,使得每个值都用一个 8 位整数表示 (缩小 4 倍)。请注意,这与二进制量化情况不同,在二进制量化中,每个值由一个单比特表示 (缩小 32 倍)。 + +#### Sentence Transformers 中的标量量化 + +将一个维度为 1024 的嵌入量化为 `int8` 将得到 1024 字节。在实际应用中,我们可以选择 `uint8` 或 `int8` 。这个选择通常取决于你的向量库/数据库支持哪种格式。 + +在实践中,建议为标量量化提供以下之一: + +1. 一大组嵌入,以便一次性全部量化,或者 +2. 每个嵌入维度的 `min` 和 `max` 范围,或者 +3. 一大组嵌入的校准数据集,从中可以计算 `min` 和 `max` 范围。 + +如果这些情况都不适用,你将收到如下警告: +`Computing int8 quantization buckets based on 2 embeddings. int8 quantization is more stable with 'ranges' calculated from more embeddings or a 'calibration_embeddings' that can be used to calculate the buckets.` +大意是如果你只使用很少量的嵌入 (在这个例子中是 2 个嵌入) 来计算这些量化桶,那么量化可能不会那么稳定或准确,因为少量的数据可能无法很好地代表整个数据分布。因此,如果你有一个很大的数据集来计算这些范围,或者有一个校准数据集,那么你可以得到更好的量化结果。 + +请看下面如何使用 [Sentence Transformers](https://sbert.net/) 生成标量量化嵌入: + +```python +from sentence_transformers import SentenceTransformer +from sentence_transformers.quantization import quantize_embeddings +from datasets import load_dataset + +# 1. Load an embedding model +model = SentenceTransformer("mixedbread-ai/mxbai-embed-large-v1") + +# 2. Prepare an example calibration dataset +corpus = load_dataset("nq_open", split="train[:1000]")["question"] +calibration_embeddings = model.encode(corpus) + +# 3. Encode some text without quantization & apply quantization afterwards +embeddings = model.encode(["I am driving to the lake.", "It is a beautiful day."]) +int8_embeddings = quantize_embeddings( + embeddings, + precision="int8", + calibration_embeddings=calibration_embeddings, +) +``` + +**参考文献:** + +mixedbread-ai/mxbai-embed-large-v1SentenceTransformer.encodequantize_embeddings + +在这里,你可以看到默认的 `float32` 嵌入和 `int8` 标量嵌入在形状、大小和 `numpy` 数据类型方面的差异: + +```python +>>> embeddings.shape +(2, 1024) +>>> embeddings.nbytes +8192 +>>> embeddings.dtype +float32 +>>> int8_embeddings.shape +(2, 1024) +>>> int8_embeddings.nbytes +2048 +>>> int8_embeddings.dtype +int8 +``` + +#### 向量数据库中的标量量化 + +| 向量数据库 | 是否支持标量量化 | +| --- | --- | +| Faiss | [IndexHNSWSQ](https://faiss.ai/cpp_api/struct/structfaiss_1_1IndexHNSWSQ.html) | +| USearch | [是](https://github.com/unum-cloud/usearch) | +| Vespa AI | [是](https://docs.vespa.ai/en/reference/tensor.html) | +| OpenSearch | [是](https://opensearch.org/docs/latest/field-types/supported-field-types/knn-vector) | +| ElasticSearch | [是](https://www.elastic.co/de/blog/save-space-with-byte-sized-vectors) |间接通过 +| Milvus | [IVF_SQ8](https://milvus.io/docs/index.md) |间接通过 +| Qdrant | [Scalar Quantization](https://qdrant.tech/documentation/guides/quantization/#scalar-quantization) | + +### 结合二进制和标量量化 + +结合二进制和标量量化可以兼得两者的优点: 二进制嵌入的极快速度和标量嵌入在重打分后的优良性能的保留。请查看下面的 [演示](#demo),这是一个涉及维基百科 4100 万文本的真实实现。该设置的流程如下: + +1. 使用 [`mixedbread-ai/mxbai-embed-large-v1`](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1) SentenceTransformer 模型对查询进行嵌入。 +2. 使用 `sentence-transformers` 库中的 quantize_embeddings 函数将查询量化为二进制。 +3. 使用量化查询在二进制索引 (4100 万个二进制嵌入; 5.2GB 内存/磁盘空间) 中搜索前 40 个文档。 +4. 从磁盘上的 int8 索引 (4100 万个 int8 嵌入; 0 字节内存,47.5GB 磁盘空间) 动态加载前 40 个文档。 +5. 使用 float32 查询和 int8 嵌入对前 40 个文档进行重打分,以获得前 10 个文档。 +6. 按分数对前 10 个文档进行排序并显示。 + +通过这种方法,我们为索引使用了 5.2GB 内存和 52GB 磁盘空间。这比通常的检索所需的 200GB 内存和 200GB 磁盘空间要少得多。尤其是当你进一步扩展时,这将显著减少延迟和成本。 + +### 量化实验 + +我们在 [MTEB](https://huggingface.co/spaces/mteb/leaderboard) 的检索子集上进行了实验,该子集包含 15 个基准测试。首先,我们使用 `rescore_multiplier` 为 4 来检索前 k (k=100) 个搜索结果。因此,我们总共检索了 400 个结果,并对这前 400 个结果进行了重打分。对于 `int8` 性能,我们直接使用了点积,而没有进行任何重打分。 + +| 模型 | 嵌入维度 | 250M 嵌入 | MTEB 检索(NDCG@10) | 默认性能的百分比 | +| - | -: | -: | -: | -: | +| **开源模型** | | | | | +| [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1): float32 | 1024 | 953.67GB
$3623 / mo | 54.39 | 100% | +| [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1): int8 | 1024 | 238.41GB
$905 / mo | 52.79 | 97% | +| [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1): binary | 1024 | 29.80GB
$113.25 / mo |52.46 | 96.45% | +| [e5-base-v2](https://huggingface.co/intfloat/e5-base-v2): float32 | 768 | 286.10GB
$1087 / mo |50.77 | 100% | +| [e5-base-v2](https://huggingface.co/intfloat/e5-base-v2): int8 | 768 | 178.81GB
$679 / mo| 47.54 | 94.68% | +| [e5-base-v2](https://huggingface.co/intfloat/e5-base-v2): binary | 768 | 22.35GB
$85 / mo | 37.96 |74.77% | +| [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2): float32 | 384 | 357.62GB
$1358 / mo | 41.66 |100% +| [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2): int8 | 384 | 89.40GB
$339 / mo| 37.82 | 90.79% +| [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2): binary | 384 | 11.18GB
$42 / mo |39.07| 93.79%| +| **专有模型** | | | | | +| [Cohere-embed-english-v3.0](https://txt.cohere.com/introducing-embed-v3/): float32 | 1024 | 953.67GB
$3623 / mo | 55.0 | 100% | +| [Cohere-embed-english-v3.0](https://txt.cohere.com/introducing-embed-v3/): int8 | 1024 | 238.41GB
$905 / mo | 55.0 | 100% | +| [Cohere-embed-english-v3.0](https://txt.cohere.com/introducing-embed-v3/): binary | 1024 | 29.80GB
$113.25 / mo | 52.3 | 94.6% | + +从我们的量化实验结果中,可以识别出几个关键趋势和好处。正如预期的那样,维度更高的嵌入模型通常每计算生成的存储成本更高,但能实现最佳性能。然而,令人惊讶的是,量化到 `int8` 已经帮助 `mxbai-embed-large-v1` 和 `Cohere-embed-english-v3.0` 在存储使用低于较小维度基模型的情况下实现了更高的性能。 + +量化好处的显现,在查看二进制模型的结果时更为明显。在这种情况下,1024 维度的模型仍然优于现在存储需求高 10 倍的基模型,而 `mxbai-embed-large-v1` 在资源需求减少 32 倍后仍能保持超过 96% 的性能。从 `int8` 进一步量化到二进制的性能损失几乎可以忽略不计。 + +有趣的是,我们还可以看到 `all-MiniLM-L6-v2` 在二进制量化上的性能比 `int8` 量化更强。这可能的原因是校准数据的选择。在 `e5-base-v2` 上,我们观察到了 [维度坍缩](https://arxiv.org/abs/2110.09348) 效应,导致模型只使用潜在空间的子空间; 当进行量化时,整个空间进一步坍缩,导致性能损失很大。 + +这表明量化并不适用于所有嵌入模型。考虑现有基准测试结果并开展实验以确定给定模型与量化的兼容性仍然至关重要。 + +### 重打分的影响 + +在本节中,我们探讨了重打分对检索性能的影响。我们基于 [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1) 评估了结果。 + +#### 二进制重打分 + +使用二进制嵌入,[mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1) 在 MTEB 检索上保留了 92.53% 的性能。仅进行重打分而无需检索更多样本,性能提升到了 96.45%。我们实验设置了 `rescore_multiplier` 从 1 到 10,但没有观察到进一步的性能提升。这表明 `top_k` 搜索已经检索到了最顶级的候选项,而重打分则正确地重新排列了这些好的候选项。 + +#### 标量 (Int8) 重打分 + +我们还评估了 [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1) 模型与 `int8` 重打分,因为 Cohere 表明 [Cohere-embed-english-v3.0](https://txt.cohere.com/introducing-embed-v3/) 在 `int8` 量化后可以达到 `float32` 模型的 100% 性能。在这个实验中,我们将 `rescore_multiplier` 设置为 [1, 4, 10],并得到了以下结果: + +

+ +

+ +从图表中我们可以看到,更高的重打分乘数意味着量化后性能的更好保留。从我们的结果推断,我们假设这种关系可能是双曲线的,随着重打分乘数的增加,性能接近 100%。使用 `int8` 时,重打分乘数为 4-5 已经导致令人瞩目的 99% 的性能保留。 + +#### 检索速度 + +我们使用 Google Cloud Platform 的 `a2-highgpu-4g` 实例,在整个 MTEB 检索中测量了 [mxbai-embed-large-v1](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1) 嵌入的检索速度,该嵌入的维度为 1024。对于 `int8` ,我们使用了 [USearch](https://github.com/unum-cloud/usearch) (版本 2.9.2) 和二进制量化 [Faiss](https://github.com/facebookresearch/faiss) (版本 1.8.0)。所有计算都在 CPU 上使用精确搜索完成。 + +| 量化 | 最小 | 均值 | 最大 | +|--------------|----------------|--------------------|---------------| +| `float32` | 1x (baseline) | **1x** (baseline) | 1x (baseline) | +| `int8` | 2.99x speedup | **3.66x** speedup | 4.8x speedup | +| `binary` | 15.05x speedup | **24.76x** speedup | 45.8x speedup | + +如表中所示,应用 `int8` 标量量化相比全尺寸 `float32` 嵌入实现了平均速度提升 3.66 倍。此外,二进制量化实现了平均速度提升 24.76 倍。对于标量和二进制量化,即使在最坏的情况下,也实现了非常显著的速度提升。 + +### 性能汇总 + +量化在资源使用、检索速度和检索性能方面的实验结果和影响可以总结如下: + +| | float32 | int8/uint8 | binary/ubinary | +|-------------------------------|---------:|------------:|----------------:| +| **内存和索引空间节省** | 1x | 精确 4x | 精确 32x | +| **检索速度** | 1x | 多达 4x | 多达 45x | +| **默认性能百分比** | 100% | ~99.3% | ~96% | + +### 演示 + +以下 [演示](https://huggingface.co/spaces/sentence-transformers/quantized-retrieval) 展示了通过结合二进制搜索和标量 ( `int8` ) 重打分来提高检索效率。该解决方案需要 5GB 的内存用于二进制索引和 50GB 的磁盘空间用于二进制和标量索引,这比常规的 `float32` 检索所需的 200GB 内存和磁盘空间要少得多。此外,检索速度也更快。 + + + +### 自己尝试 + +以下脚本可用于实验性地进行检索和其他用途的嵌入量化。它们分为三个类别: + +- **推荐检索**: + + - [semantic_search_recommended.py](https://github.com/UKPLab/sentence-transformers/blob/master/examples/applications/embedding-quantization/semantic_search_recommended.py): 此脚本结合了二进制搜索和标量重打分,与上面的演示类似,以实现廉价、高效且性能良好的检索。 + +- **使用**: + + - [semantic_search_faiss.py](https://github.com/UKPLab/sentence-transformers/blob/master/examples/applications/embedding-quantization/semantic_search_faiss.py): 此脚本展示了使用 FAISS 的常规二进制或标量量化、检索和重打分的使用方式,通过使用 semantic_search_faiss 实用函数。 + - [semantic_search_usearch.py](https://github.com/UKPLab/sentence-transformers/blob/master/examples/applications/embedding-quantization/semantic_search_usearch.py): 此脚本展示了使用 USearch 的常规二进制或标量量化、检索和重打分的使用方式,通过使用 semantic_search_usearch 实用函数。 + +- **基准测试**: + + - [semantic_search_faiss_benchmark.py](https://github.com/UKPLab/sentence-transformers/blob/master/examples/applications/embedding-quantization/semantic_search_faiss_benchmark.py): 此脚本包括了对 `float32` 检索、二进制检索加重打分和标量检索加重打分的检索速度基准测试,使用 FAISS。它使用了 semantic_search_faiss 实用函数。我们的基准测试特别显示了 `ubinary` 的速度提升。 + - [semantic_search_usearch_benchmark.py](https://github.com/UKPLab/sentence-transformers/blob/master/examples/applications/embedding-quantization/semantic_search_usearch_benchmark.py): 此脚本包括了对 `float32` 检索、二进制检索加重打分和标量检索加重打分的检索速度基准测试,使用 USearch。它使用了 semantic_search_usearch 实用函数。我们的实验在新硬件上显示了巨大的速度提升,特别是对于 `int8` 。 + +### 未来工作 + +我们期待二进制量化技术的进一步发展。要提到的一些潜在改进,我们怀疑可能还有比 `int8` 更小的标量量化空间,即使用 128 或 64 个桶而不是 256 个。 + +此外,我们也很兴奋地发现,嵌入量化与 Matryoshka 表征学习 (MRL) 完全垂直。换句话说,可以将 MRL 嵌入从例如 1024 减少到 128 (通常与 2% 的性能降低相对应),然后应用二进制或标量量化。我们怀疑这可能会将检索速度提高多达 32 倍,质量降低约 3%,或者质量降低约 10% 时检索速度提高多达 256 倍。 + +最后,我们意识到,使用嵌入量化进行检索可以与一个独立的重新排序模型结合起来使用。我们设想了一个三步流水线: 首先进行二进制搜索,然后对结果进行标量 (int8) 重打分,最后使用交叉编码模型进行重新排序。这样的流水线可以实现高效的检索性能,同时降低延迟、内存使用、磁盘空间和成本。 + +### 致谢 + +这个项目得益于我们与 [mixedbread.ai](https://mixedbread.ai) 的合作以及 [SentenceTransformers](https://www.sbert.net/) 库,该库允许你轻松创建句子嵌入并进行量化。如果你想在你的项目中使用量化嵌入,你现在知道该怎么做了! + +### 引用 + +```bibtex +@article{shakir2024quantization, + author = { Aamir Shakir and + Tom Aarsen and + Sean Lee + }, + title = { Binary and Scalar Embedding Quantization for Significantly Faster & Cheaper Retrieval }, + journal = {Hugging Face Blog}, + year = {2024}, + note = {https://huggingface.co/blog/embedding-quantization}, +} +``` + +### 参考文献 + +mixedbread-ai/mxbai-embed-large-v1SentenceTransformer.encodequantize_embeddings +- [Sentence Transformers docs - Embedding Quantization](https://sbert.net/examples/applications/embedding-quantization/README.html) +- https://txt.cohere.com/int8-binary-embeddings/ +- https://qdrant.tech/documentation/guides/quantization +- https://zilliz.com/learn/scalar-quantization-and-product-quantization diff --git a/zh/google-cloud-model-garden.md b/zh/google-cloud-model-garden.md new file mode 100644 index 0000000000..dbe0e137e8 --- /dev/null +++ b/zh/google-cloud-model-garden.md @@ -0,0 +1,61 @@ +--- +title: "在 Google Cloud 上轻松部署开放大语言模型" +thumbnail: /blog/assets/173_gcp-partnership/thumbnail.jpg +authors: +- user: philschmid +- user: jeffboudier +translators: +- user: chenglu +--- + +# 在 Google Cloud 上轻松部署开放大语言模型 + +今天,我们想向大家宣布:“**在 Google Cloud 上部署**”功能正式上线! + +这是 Hugging Face Hub 上的一个新功能,让开发者可以轻松地将数千个基础模型使用 Vertex AI 或 Google Kubernetes Engine (GKE) 部署到 Google Cloud。 + +Model Garden (模型库) 是 Google Cloud Vertex AI 平台的一个工具,用户能够发现、定制和部署来自 Google 及其合作伙伴的各种模型。不论是在 Hugging Face 模型页面还是在 Vertex AI 模型库页面,开发者们都可以轻松简单地将开放模型作为 API 端点部署在自己的 Google Cloud 账户内。我们也将启用 Hugging Face 上最受欢迎的开放模型进行推理,这一切都得益于我们的生产级解决方案 [文本生成推理](https://github.com/huggingface/text-generation-inference/)。 + +借助“在 Google Cloud 上部署”,开发者可以在自己的安全 Google Cloud 环境中直接构建准备就绪的生成式 AI 应用,无需自行管理基础设施和服务器。 + +## 为 AI 开发者构建 + +这一全新的体验是基于我们今年早些时候宣布的 [战略合作关系](https://huggingface.co/blog/gcp-partnership) 进一步扩展的,目的是简化 Google 客户访问和部署开放生成式 AI 模型的过程。开发者和机构面临的一个主要挑战是,部署模型需要投入大量时间和资源,且必须确保部署的安全性和可靠性。 + +“在 Google Cloud 上部署”提供了一个简单且管理化的解决方案,专为 Hugging Face 模型提供了专门的配置和资源。只需简单点击几下,就可以在 Google Cloud 的 Vertex AI 上创建一个准备就绪的端点。 + +Google 产品经理 Wenming Ye 表示:“Vertex AI 的 Model Garden 与 Hugging Face Hub 的集成,让在 Vertex AI 和 GKE 上发现和部署开放模型变得无缝衔接,无论您是从 Hub 开始,还是直接在 Google Cloud 控制台中。我们迫不及待想看到 Google 开发者们将会用 Hugging Face 模型创建出什么样的创新。” + +## 从 HF Hub 开启模型部署 + +在 Google Cloud 上部署 Hugging Face 模型变得非常简单。以下是如何部署 [Zephyr Gemma](https://console.cloud.google.com/vertex-ai/publishers/HuggingFaceH4/model-garden/zephyr-7b-gemma-v0.1;hfSource=true;action=deploy?authuser=1) 的步骤指导。从今天开始,所有带有 [text-generation-inference](https://huggingface.co/models?pipeline_tag=text-generation-inference&sort=trending) 标签的模型都将受到支持。 + +![model-card](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/google-cloud-model-garden/model-card.png) + +只需打开“部署”菜单,选择“Google Cloud”即可。这将直接带您进入 Google Cloud 控制台,您可以在 Vertex AI 或 GKE 上轻松一键部署 Zephyr Gemma。 + +![vertex-ai-model-garden](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/google-cloud-model-garden/vertex-ai-model-garden.png) + +进入 Vertex AI 模型库之后,您可以选择 Vertex AI 或 GKE 作为部署环境。如果选择 Vertex AI,您可以通过点击“部署”一键完成部署过程。如果选择 GKE,您可以根据提供的指南和模板,在新建或现有的 Kubernetes 集群上部署模型。 + +## 从 Vertex AI 模型库开启模型部署 + +Vertex AI 模型库是 Google 开发者寻找可用于生成式 AI 项目的现成模型的理想场所。从今天开始,Vertex Model Garden 将提供一种全新的体验,使开发者能够轻松部署 Hugging Face 上可用的最流行的开放大语言模型! + +在 Google Vertex AI 模型库中,您会发现一个新的“从 Hugging Face 部署”选项,允许您直接在 Google Cloud 控制台内搜索并部署 Hugging Face 模型。 + +![deploy-from-huggingface.png](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/google-cloud-model-garden/deploy-from-huggingface.png) + +点击“从 Hugging Face 部署”后,将显示一个表单,您可以在其中快速查找模型 ID。Hugging Face 上数以百计最受欢迎的开放大语言模型已经准备就绪,提供了经过测试的硬件配置。 + +![model-selection.png](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/google-cloud-model-garden/model-selection.png) + +找到想要部署的模型后,选择该模型,Vertex AI 会自动填充所有必要的配置,以便您将模型部署到 Vertex AI 或 GKE 上。通过“在 Hugging Face 上查看”功能,您甚至可以确认选择的模型是否正确。如果您使用的是受限模型,请确保提供您的 Hugging Face 访问令牌,以授权下载模型。 + +![from-deploy.png](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/google-cloud-model-garden/from-deploy.png) + +就是这样!从 Vertex AI 模型库直接将模型如 Zephyr Gemma 部署到您的 Google Cloud 账户,只需简单几步。 + +## 这只是开始 + +我们很高兴能够与 Google Cloud 合作,让 AI 更加开放和易于访问。无论是从 Hugging Face Hub 开始,还是在 Google Cloud 控制台内,部署开放模型到 Google Cloud 上都变得前所未有的简单。但我们不会止步于此——敬请期待,我们将开启更多在 Google Cloud 上利用开放模型构建 AI 的新体验! \ No newline at end of file diff --git a/zh/phi2-intel-meteor-lake.md b/zh/phi2-intel-meteor-lake.md new file mode 100644 index 0000000000..29b9a58736 --- /dev/null +++ b/zh/phi2-intel-meteor-lake.md @@ -0,0 +1,164 @@ +--- +title: "笔记本电脑上的聊天机器人:在英特尔 Meteor Lake 上运行 Phi-2" +thumbnail: /blog/assets/phi2-intel-meteor-lake/02.jpg +authors: +- user: juliensimon +- user: echarlaix +- user: ofirzaf + guest: true +- user: imargulis + guest: true +- user: guybd + guest: true +- user: moshew + guest: true +translators: +- user: MatrixYao +- user: zhongdongy + proofreader: true +--- + +# 笔记本电脑上的聊天机器人: 在英特尔 Meteor Lake 上运行 Phi-2 + +

+  重新审视大卫与歌利亚的故事
+

+ +对应于其强大的能力,大语言模型 (LLM) 需要强大的算力支撑,而个人计算机上很难满足这一需求。因此,我们别无选择,只能将它们部署至由本地或云端托管的性能强大的定制 AI 服务器上。 + +## 为何需要将 LLM 推理本地化 + +如果我们可以在典配个人计算机上运行最先进的开源 LLM 会如何?好处简直太多了: + +- **增强隐私保护**: 私有数据不需要发送至外部 API 进行推理。 +- **降低延迟**: 节省网络往返的次数。 +- **支持离线工作**: 用户可以在没有网络连接的情况下使用 LLM (常旅客的梦想!)。 +- **降低成本**: 无需在 API 调用或模型托管上花一分钱。 +- **可定制**: 每个用户都可以找到最适合他们日常工作任务的模型,甚至可以对其进行微调或使用本地检索增强生成 (RAG) 来提高适配度。 + +这一切的一切都太诱人了!那么,为什么我们没有这样做呢?回到我们的开场白,一般典配笔记本电脑没有足够的计算能力来运行具有可接受性能的 LLM。它们既没有数千核的 GPU,也没有快如闪电的高内存带宽。 + +接受失败,就此放弃?当然不! + +## 为何现在 LLM 推理本地化有戏了 + +聪明的人类总能想到法子把一切东西变得更小、更快、更优雅、更具性价比。近几个月来,AI 社区一直在努力在不影响其预测质量的前提下缩小模型。其中,有三个领域的进展最振奋人心: + +- **硬件加速**: 现代 CPU 架构内置了专门用于加速最常见的深度学习算子 (如矩阵乘或卷积) 的硬件,这使得在 AI PC 上使能新的生成式 AI 应用并显著提高其速度和效率成为可能。 + +- **小语言模型 (Small Language Models,SLMs)**: 得益于在模型架构和训练技术上的创新,这些小模型的生成质量与大模型相当甚至更好。同时,由于它们的参数较少,推理所需的计算和内存也较少,因此非常适合资源受限的设备。 + +- **量化**: 量化技术通过减少模型权重和激活的位宽来降低内存和计算要求,如将权重和激活从 16 位浮点 ( `fp16` ) 降至 8 位整型 ( `int8` )。减少位宽意味着模型推理时的内存需求更少,因而能加速内存受限步骤 (如文本生成的解码阶段) 的延迟。此外,权重和激活量化后,能充分利用 AI 加速器的整型运算加速模块,因而可以加速矩阵乘等运算。 + +本文,我们将综合利用以上三种技术对微软 [Phi-2](https://huggingface.co/microsoft/phi-2) 模型进行 4 比特权重量化,随后在搭载英特尔 Meteor Lake CPU 的中端笔记本电脑上进行推理。在此过程中,我们主要使用集成了英特尔 OpenVINO 的 Hugging Face [Optimum Intel](https://github.com/huggingface/optimum-intel) 库。 + +> **_注意_**: 如果你想同时量化权重和激活的话,可参阅 [该文档](https://huggingface.co/docs/optimum/main/en/intel/optimization_ov#static-quantization)。 + +我们开始吧。 + +## 英特尔 Meteor Lake + +英特尔 Meteor Lake 于 2023 年 12 月推出,现已更名为 [Core Ultra](https://www.intel.com/content/www/us/en/products/details/processors/core-ultra.html),其是一个专为高性能笔记本电脑优化的全新 [架构](https://www.intel.com/content/www/us/en/content-details/788851/meteor-lake-architecture-overview.html)。 + +Meteor Lake 是首款使用 chiplet 架构的英特尔客户端处理器,其包含: + +- 高至 16 核的 **高能效 CPU**, + +- **集成显卡 (iGPU)**: 高至 8 个 Xe 核心,每个核心含 16 个 Xe 矢量引擎 (Xe Vector Engines,XVE)。顾名思义,XVE 可以对 256 比特的向量执行向量运算。它还支持 DP4a 指令,该指令可用于计算两个宽度为 4 字节的向量的点积,将结果存储成一个 32 位整数,并将其与另一个 32 位整数相加。 + +- **神经处理单元 (Neural Processing Unit,NPU)**,是英特尔架构的首创。NPU 是专为客户端 AI 打造的、高效专用的 AI 引擎。它经过优化,可有效处理高计算需求的 AI 计算,从而释放主 CPU 和显卡的压力,使其可处理其他任务。与利用 CPU 或 iGPU 运行 AI 任务相比,NPU 的设计更加节能。 + +为了运行下面的演示,我们选择了一台搭载了 [Core Ultra 7 155H CPU](https://www.intel.com/content/www/us/en/products/sku/236847/intel-core-ultra-7-processor-155h-24m-cache-up-to-4-80-ghz/specifications.html) 的 [中端笔记本电脑](https://www.amazon.com/MSI-Prestige-Evo-Laptop-A1MG-029US/dp/B0CP9Y8Q6T/)。现在,我们选一个可爱的小语言模型到这台笔记本电脑上跑跑看吧! + +> **_注意_**: 要在 Linux 上运行此代码,请先遵照 [此说明](https://docs.openvino.ai/2024/get-started/configurations/configurations-intel-gpu.html) 安装 GPU 驱动。 + +## 微软 Phi-2 模型 + +微软于 2023 年 12 月 [发布](https://www.microsoft.com/en-us/research/blog/phi-2-the-surprising-power-of-small-language-models/) 了 [Phi-2](https://huggingface.co/microsoft/phi-2) 模型,它是一个 27 亿参数的文本生成模型。 + +微软给出的基准测试结果表明,Phi-2 并未因其较小的尺寸而影响生成质量,其表现优于某些最先进的 70 亿参数和 130 亿参数的 LLM,甚至与更大的 Llama-2 70B 模型相比也仅有一步之遥。 + + + + + +这使其成为可用于笔记本电脑推理的有利候选。另一个候选是 11 亿参数的 [TinyLlama](https://huggingface.co/TinyLlama/TinyLlama-1.1B-Chat-v1.0) 模型。 + +现在,让我们看看如何缩小模型以使其更小、更快。 + +## 使用英特尔 OpenVINO 和 Optimum Intel 进行量化 + +英特尔 OpenVINO 是一个开源工具包,其针对许多英特尔硬件平台对 AI 推理工作负载进行优化 ([Github](https://github.com/openvinotoolkit/openvino)、[文档](https://docs.openvino.ai/2024/home.html)),模型量化是其重要特性之一。 + +我们与英特尔合作,将 OpenVINO 集成至 Optimum Intel 中,以加速 Hugging Face 模型在英特尔平台上的性能 ([Github](https://github.com/huggingface/optimum-intel),[文档](https://huggingface.co/docs/optimum/intel/index))。 + +首先,请确保你安装了最新版本的 `optimum-intel` 及其依赖库: + +```bash +pip install --upgrade-strategy eager optimum[openvino,nncf] +``` + +`optimum-intel` 支持用户很容易地把 Phi-2 量化至 4 比特。我们定义量化配置,设置优化参数,并从 Hub 上加载模型。一旦量化和优化完成,我们可将模型存储至本地。 + +```python +from transformers import AutoTokenizer, pipeline +from optimum.intel import OVModelForCausalLM, OVWeightQuantizationConfig + +model_id = "microsoft/phi-2" +device = "gpu" +# Create the quantization configuration with desired quantization parameters +q_config = OVWeightQuantizationConfig(bits=4, group_size=128, ratio=0.8) + +# Create OpenVINO configuration with optimal settings for this model +ov_config = {"PERFORMANCE_HINT": "LATENCY", "CACHE_DIR": "model_cache", "INFERENCE_PRECISION_HINT": "f32"} + +tokenizer = AutoTokenizer.from_pretrained(model_id) +model = OVModelForCausalLM.from_pretrained( + model_id, + export=True, # export model to OpenVINO format: should be False if model already exported + quantization_config=q_config, + device=device, + ov_config=ov_config, + ) + +# Compilation step : if not explicitly called, compilation will happen before the first inference +model.compile() +pipe = pipeline("text-generation", model=model, tokenizer=tokenizer) +results = pipe("He's a dreadful magician and") + +save_directory = "phi-2-openvino" +model.save_pretrained(save_directory) +tokenizer.save_pretrained(save_directory) +``` + +`ratio` 参数用于控制将多少权重量化为 4 比特 (此处为 80%),其余会量化至 8 比特。 `group_size` 参数定义了权重量化组的大小 (此处为 128),每个组都具有独立的缩放因子。减小这两个值通常会提高准确度,但同时会牺牲模型尺寸和推理延迟。 + +你可以从我们的 [文档](https://huggingface.co/docs/optimum/main/en/intel/optimization_ov#weight-only-quantization) 中获取更多有关权重量化的信息。 + +> **_注意_**: 你可在 [Github 上](https://github.com/huggingface/optimum-intel/blob/main/notebooks/openvino/quantized_generation_demo.ipynb) 找到完整的文本生成示例 notebook。 + +那么,在我们的笔记本电脑上运行量化模型究竟有多快?请观看以下视频亲自体验一下!播放时,请选择 1080p 分辨率以获得最大清晰度。 + +在第一个视频中,我们向模型提了一个高中物理问题: “_Lily has a rubber ball that she drops from the top of a wall. The wall is 2 meters tall. How long will it take for the ball to reach the ground?_” + + + +在第二个视频中,我们向模型提了一个编码问题: “_Write a class which implements a fully connected layer with forward and backward functions using numpy. Use markdown markers for code._” + + + +如你所见,模型对这两个问题生成的答案质量都非常高。量化加快了生成速度,但并没有降低 Phi-2 的质量。我本人很愿意在我的笔记本电脑上每天使用这个模型。 + +## 总结 + +借助 Hugging Face 和英特尔的工作,现在你可以在笔记本电脑上运行 LLM,并享受本地推理带来的诸多优势,如隐私、低延迟和低成本。我们希望看到更多好模型能够针对 Meteor Lake 平台及其下一代平台 Lunar Lake 进行优化。Optimum Intel 库使得在英特尔平台上对量化模型变得非常容易,所以,何不试一下并在 Hugging Face Hub 上分享你生成的优秀模型呢?多多益善! + +下面列出了一些可帮助大家入门的资源: + +- Optimum Intel [文档](https://huggingface.co/docs/optimum/main/en/intel/inference) +- 来自英特尔及 Hugging Face 的 [开发者资源](https://www.intel.com/content/www/us/en/developer/partner/hugging-face.html) +- 深入探讨模型量化的视频: [第 1 部分](https://youtu.be/kw7S-3s50uk)、[第 2 部分](https://youtu.be/fXBBwCIA0Ds) + +如若你有任何问题或反馈,我们很乐意在 [Hugging Face 论坛](https://discuss.huggingface.co/) 上解答。 + +感谢垂阅! \ No newline at end of file