新闻
模型
API
keyboard_arrow_down
读取器
读取URL或搜索为大模型提供更好的依据。
向量模型
世界一流的多模态多语言向量模型。
重排器
世界一流的重排器,最大限度地提高搜索相关性。
MCP terminal命令行articlellms.txtsmart_toy代理人data_object模式menu_book文档



登录
login
基础 GGUF 和量化 GGUF
使用方法和注意事项
通过 llama-embedding 实现高效向量模型生成
基准测试
结论
技术博客
八月 13, 2025

针对仅解码器向量模型的 GGUF 优化

在 L4 GPU 上,一个 30 亿参数的向量模型达到 4000 词元/秒的速度,这可能已经是使用 llama.cpp 所能达到的最快速度了。真的是这样吗?
Han Xiao
Han Xiao • 15 分钟的读取量

两周前,我们发布了 jina-embeddings-v4 的 GGUF 格式版本,这是一个用于多模态多语言检索的通用 向量模型,包含各种量化版本。我们的动机很简单:作为一个 3.75B 参数的模型,原始 transformer 版本的 jina-embeddings-v4 在我们的 GCP G2 (L4 GPU) API 实例上扩展性不佳,因此我们希望使用这些更小、更快的 GGUF 版本来加速推理。在我们的实验中,我们在转换和运行 GGUF 向量模型时发现了一些有趣的发现。由于大多数 llama.cpp 社区都专注于 大模型,我们认为从 向量模型 提供商的角度分享这一点会很有价值。

特别相关的是,今天的 向量模型 几乎与 大模型 完全相同——例如,jina-embeddings-v4 基于 Qwen2.5-VL-3B-instruct,而 jina-reranker-m0 基于 Qwen2-VL-2B。唯一的真正区别在于输出: 大模型 是生成式的,而 向量模型 和 重排器 是判别式的。这既带来了机遇也带来了挑战:一方面,我们可以利用 llama.cpp 的高效实现(例如 ubatch_size)来服务 向量模型 / 重排器 模型;另一方面,llama.cpp 的 向量模型 实现主要为较旧的仅编码器架构(如基于 RoBERTa 的模型)开发,尚未完全赶上现代仅解码器 向量模型 / 重排器 模型。本文分享了我们在调整现代 向量模型 以使用 GGUF 格式和 llama.cpp 工具(例如 llama-embedding 和 llama-serving)时所学到的知识。

tag基础 GGUF 和量化 GGUF

jina-embeddings-v4 基于 Qwen2.5-VL-3B-instruct,带有三个 LoRA 适配器:retrieval(针对检索任务进行了优化)、text-matching(针对句子相似性任务进行了优化)和 code(针对代码检索任务进行了优化)。它还经过大量训练,用于视觉文档检索和后期交互风格的多向量输出。因此,这里的想法是利用 llama.cpp 现有的 Qwen2.5-VL-3B 图实现,并使用 llama-embedding 进行推理。

但是,我们首先注意到的是 llama.cpp 中 mmproj 或视觉 transformer 实现中的错误行为,这导致对于相同的图像输入,其产生的 向量模型 与 torch 实现的 Qwen2.5-VL-3B 不同。在我们 在我们的 fork 中 修复此问题时,我们决定暂时从 GGUF 版本中排除视觉 tower。您可以在此处找到有关此讨论的更多详细信息。

Multi-modal embeddings for jinaai/jina-embeddings-v4 · ggml-org llama.cpp · Discussion #14851
Hey folks! I’m working on getting multimodal embeddings working with jina-embeddings-v4 (based on Qwen 2.5 VL) through llama.cpp server. I’ve hit an issue with mtmd inconsistencies and was hoping s…
GitHubggml-org

多向量 向量模型 输出 也不是开箱即用的,但它不像视觉 transformers 那样是一个大问题。多向量输出来自最后一个 transformer 块中训练的 MLP,因此最坏的情况是,我们可以始终将此 MLP 单独导出到 numpy,并在从 llama.cpp 获得 token 级别的 向量模型 后应用它——这就是我们为 jina-reranker-m0-GGUF 所做的事情。 当然,这不是很有效,但它可以在无需修改和重新编译 llama.cpp 的情况下工作。

0:00
/0:04

我们去掉了视觉 transformer 和多向量投影仪,并获得了三个 F16 中的基本 GGUF 模型。

因此,为了完全符合 llama.cpp 现有的 Qwen2.5-VL-3B 图实现,我们去掉了视觉 transformer 和最后一个 transformer 块中的多向量投影仪,并将所有 LoRA 适配器合并回基本语言模型。这为我们提供了三个特定于任务的 v4 模型,每个模型有 3.09B 个参数——低于原始 v4 的 3.75B 个参数:

HuggingFace Repo Task
jinaai/jina-embeddings-v4-text-retrieval-GGUF Text retrieval
jinaai/jina-embeddings-v4-text-code-GGUF Code retrieval
jinaai/jina-embeddings-v4-text-matching-GGUF Sentence similarity

然后,我们使用了 calibration_data_v5_rc.txt(可以在此处找到,并且是 Unsloth 推荐的)来校准所有三个基本 GGUF 模型,并获得了三个 imatrix 文件,然后使用带有 imatrix 的 llama-quantize 将模型从 float16 量化,如下所示:

# build imatrix
llama-imatrix -m jina-embeddings-v4-text-retrieval-F16.gguf -f calibration_data_v5_rc.txt -ngl 99 --no-ppl -o imatrix-retrieval-512.dat

# quantize
./quantize.sh jina-embeddings-v4-text-retrieval-F16.gguf retrieval-i3 imatrix-retrieval-512.dat jinaai/jina-embeddings-v4-text-retrieval-GGUF

quantize.sh 脚本如下所示:

#!/bin/bash

F16_MODEL_FILE="$1"
OUTPUT_DIR="$2"
IMATRIX="$3"
HF_REPO="$4"

FILENAME="$(basename "$F16_MODEL_FILE")"
BASE_NAME="${FILENAME%-F16.gguf}"
BASE_NAME="${BASE_NAME%.gguf}"

mkdir -p "$OUTPUT_DIR"

# Array of quantization types
QUANT_TYPES=("IQ1_S" "IQ1_M" "IQ2_XXS" "IQ2_M" "Q2_K" "IQ4_NL" "IQ4_XS"  "IQ3_XXS" "IQ3_S" "IQ3_M" "IQ3_XS" "Q3_K_M" "Q4_K_M" "Q5_K_S" "Q5_K_M" "Q6_K" "Q8_0")

for quant_type in "${QUANT_TYPES[@]}"; do
    llama-quantize --imatrix "${IMATRIX}" "$F16_MODEL_FILE" "${OUTPUT_DIR}/${BASE_NAME}-${quant_type}.gguf" $quant_type 8
done

最终,我们将所有量化上传到了 HuggingFace。

量化 BPW 文件大小 (GB)
IQ1_S 2.04 0.73
IQ1_M 2.19 0.79
IQ2_XXS 2.44 0.88
IQ2_M 2.94 1.06
Q2_K 3.29 1.18
IQ3_XXS 3.31 1.19
IQ3_XS 3.59 1.29
IQ3_S 3.76 1.35
IQ3_M 3.84 1.38
Q3_K_M 4.11 1.48
IQ4_NL 4.72 1.69
IQ4_XS 4.49 1.61
Q4_K_M 4.99 1.79
Q5_K_S 5.61 2.02
Q5_K_M 5.75 2.07
Q6_K 6.56 2.36
Q8_0 8.50 3.05
F16 16.00 5.75
v3 (Transformers) 16.00 1.10
v4 (Transformers) 16.00 7.40

tag使用方法和注意事项

现在我们可以使用 llama-server 和 llama-embedding 来为 GGUF 提供向量模型服务。与 Transformer 库不同,在 Transformer 库中,我们可以灵活地编写自定义的输入预处理代码,而在这里我们必须手动处理这一部分(除非我们想重新编译 llama-server 和 llama-embedding)。具体来说,为了获得与使用 AutoModel.from_pretrained("jinaai/jina-embeddings-v4")... 完全一致的结果,您需要非常小心前缀,并手动将其添加到您的 GGUF 模型输入中。以下是一个参考表:

任务 Transformer 实现中的 prompt_name 模型的实际输入
retrieval query (默认) Query: {original_text}
retrieval passage Passage: {original_text}
text-matching query (默认) Query: {original_text}
text-matching passage Query: {original_text} ⚠️
code query (默认) Query: {original_text}
code passage Passage: {original_text}

有些用户可能会觉得⚠️很奇怪,即在使用原始的 AutoModel.from_pretrained("jinaai/jina-embeddings-v4").... 中的 text-matching 时,prompt_name='passage' 会被覆盖为 "Query: "。但实际上这是有道理的,因为 text-matching 是一项句子相似度任务,没有左右角色之分——输入是对称的。

tag通过 llama-server

安装 llama.cpp 后,您可以运行 llama-server 来将向量模型托管为与 OpenAI API 兼容的 HTTP 服务器。例如,要将 text-matching 与 F16 一起使用,您可以这样做:

llama-server -hf jinaai/jina-embeddings-v4-text-matching-GGUF:F16 --embedding --pooling mean -ub 8192

--pooling mean 是必需的,因为 v4 是均值池化向量模型。

然后通过以下方式发送请求:

curl -X POST "http://127.0.0.1:8080/v1/embeddings" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [
      "Query: A beautiful sunset over the beach",
      "Query: Un beau coucher de soleil sur la plage",
      "Query: 海滩上美丽的日落",
      "Query: 浜辺に沈む美しい夕日"
    ]
  }'

当使用 retrieval 和 code 模型时,在输入前添加 Query: 或 Passage:,如下所示:

curl -X POST "http://127.0.0.1:8080/v1/embeddings" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [
      "Query: A beautiful sunset over the beach",
      "Query: Un beau coucher de soleil sur la plage",
      "Passage: 海滩上美丽的日落",
      "Passage: 浜辺に沈む美しい夕日"
    ]
  }'

tag通过 llama-embedding

为了快速进行健全性检查,您还可以使用预编译的 llama-embedding 进行一次性向量模型生成。我们不建议将其用于批量向量模型生成,因为它存在一些性能问题,我们将在下一节中讨论:

llama-embedding -hf jinaai/jina-embeddings-v4-text-matching-GGUF:F16 --pooling mean -p "Query: jina is awesome" --embd-output-format json  2>/dev/null

阅读下一节,了解如何使用我们构建的 llama-embedding 进行更高效的批量向量模型生成,其中包含一些修复和改进。

tag注意事项总结

在转向更高效的实现之前,让我们总结一下 GGUF 模型的注意事项:

  • 您必须手动在文本输入前添加 Query: 或 Passage: 。
  • 它们现在无法处理图像输入,因为我们从 GGUF 模型中删除了视觉 Transformer。我们不得不删除它们,因为 llama.cpp 的视觉 Transformer/mmproj 实现 Qwen2.5-vl-3b 存在错误,我们 正在与上游合作修复。
  • 它们无法输出多向量向量模型,因为它不是 llama.cpp 的 Qwen2.5-vl-3b 图实现的一部分。在不重新编译 llama.cpp 的情况下,最简单的解决方法是在通过在 llama-embedding 中设置 --pooling none 获取词元级别的向量模型后,单独导出并运行 MLP。
  • v4 是使用 Matryoshka 表征学习训练的,转换为 GGUF 保留了此功能。如果您获得的向量模型的形状为 NxD,则只需使用 embeddings[:, :truncate_dim] 即可获得较小的截断向量模型。但是,并非每个维度都经过训练。对于 v4,我们为这些特定值训练了 truncate_dim:[128, 256, 512, 1024, 2048]。这意味着 embeddings[:, :131] 的质量不会是 embeddings[:, :128] 和 embeddings[:, :256] 质量之间的一些插值,而是会明显低于 128 维或 256 维向量模型,因为 131 维没有经过训练。
  • 在通过 --pooling none 获取词元级别的向量模型后,延迟分块仍然可以作为后处理的一部分工作。就像我们从 llama.cpp 图中分离 MLP 所做的那样,这不是很有效,但不需要重新编译。但是,还有另一个注意事项:由于 v4 是一个因果模型,延迟分块将不再是双向的——较早的分块向量模型将不包含来自后续分块的上下文信息。请记住,在 v3 中,每个分块向量模型都具有全局上下文信息,因为我们在 Transformer 块中使用了双向注意力掩码。在内部,我们讨论了因果关系是否使延迟分块过时:有些人认为“上下文也是因果关系”——意味着读者从左到右处理文本,因此解释句子的上下文应该来自前面的文本。其他人说,将延迟分块限制为单向会阻止分块之间的上下文共享。无论哪种方式,延迟分块在 v4 中的有效性仍然值得怀疑,需要进一步研究。

tag通过 llama-embedding 实现高效向量模型生成

llama-embedding 是 llama.cpp 之上一个相对简单的 C++ 封装器,用于使用非常清晰的 I/O(stdin、stdout)对文本进行向量模型生成。我们目前专注于改进这一点,而不是 llama-server,因为还有大量其他问题,如网络排队、负载平衡、多租户和序列化,我们认为这些问题目前超出了范围。我们的问题很简单:我们可以从 L4 24GB GPU 获得多少速度,以及用于向量模型生成长文档的峰值 VRAM 使用量是多少?

但为什么是 L4?主要是因为 GCP 在其之上提供了非常方便的 Cloud Run 函数,并且它是您可以获得的用于无服务器推理 API 的最广泛可用且经济的 GPU 类型。GCP 确实按需在 Cloud Run 上提供 A100 和 H100,并且 GCP 团队时不时地会向我们推销使用更好的 GPU。但我们的理念很简单:如果我们需要 A100/H100 来服务一个 3B 模型,那显然是我们的技能问题。

作为一些背景知识,在 llama.cpp 中,逻辑批处理大小(-b) 表示在单次评估调用中提交给模型的最大词元数。在处理长输入时,它们会被分割成不超过此大小的块。**物理批次大小** (-ub) 是通过硬件一次前向传递同时处理的实际词元数,受可用内存的限制。KV 缓存会在每个物理批次完成后更新。**上下文窗口** (-c) 是模型一次可以“看到”的词元数量的硬性限制 - 对于 v4 模型,这是 32,000 个词元,代表了模型最大注意力范围。所有词元都必须在此上下文窗口内,以保持整个序列中连贯的注意力。下图说明了它们之间的关系。

tag我们的修复

GitHub - hanxiao/llama.cpp: LLM inference in C/C++
LLM inference in C/C++. Contribute to hanxiao/llama.cpp development by creating an account on GitHub.
GitHubhanxiao

在我们上面的 fork 中,我们进行了一些优化,以提高 llama-embedding 的效率:

  • 简化批处理:我们自动将 -b 设置为等于 -c,实际上使该参数变得过时。用户不再需要指定 -b,因为我们始终利用模型的完整上下文长度进行逻辑批处理。
  • 灵活的内存控制:与原始实现中强制 -ub 等于 -b(因为他们假设向量模型不是因果关系)不同,我们允许用户独立设置 -ub。这提供了对编码长上下文时峰值 VRAM 使用的细粒度控制 - 由于 KV 缓存的实现,您可以使用小的 512 词元的物理批次处理 32K 上下文,以保持在 VRAM 限制内。请注意,此更改仅适用于因果向量模型,如 jina-embeddings-v4 - 对于仅编码器架构,如 v3,这将是错误的实现。
  • 修复了平均池化:我们修正了当 ub < b 时向量模型的平均池化计算,这在原始实现中之前是错误的。

此更改使处理长上下文的仅解码器向量模型变得更加容易,同时有效地管理内存约束。现在,用户只需要配置两个参数:

    • -c:最大上下文长度(向量模型可以处理多少个词元)
    • -ub:物理批次大小(GPU 一次处理多少个词元)

因此,在 L4 上运行我们 fork 的确切代码如下:

# Compile
git clone https://github.com/hanxiao/llama.cpp.git
cd llama.cpp
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j 8

# Run
INPUT_PREFIX="Query: "  # or "Passage: "

cat big_input.txt | sed "s/^/${INPUT_PREFIX}/" | \
./llama.cpp/build/bin/llama-embedding -f /dev/stdin \
    -hf "jinaai/jina-embeddings-v4-text-retrieval-GGUF:FP16" \
    --pooling mean \
    --no-escape \
    --embd-output-format array \
    --ubatch-size 512 \
    --ctx-size 8192 \
    --flash-attn \
    -ngl 99 \
    > "embeddings.txt" 2> "error.log"

big_input.txt 中的每一行是要进行向量化的句子。应设置 --no-escape 以防止句子中的 \n 被解释为分隔符。应设置 --flash-attn 和 -ngl 99 以在 L4 GPU 上获得最佳性能。

tag基准测试

我们希望通过基准测试了解以下问题:

  • 与原始 v4 Float16 相比,我们的量化效果如何?在什么情况下,它会退化到我们最好只使用 v3 向量模型的地步?
  • 每种量化在 L4 上的运行速度有多快,以及峰值 VRAM 使用量是多少?
  • -ub 物理批次大小和 -c 上下文长度如何影响速度和峰值 VRAM?

我们在基准测试中使用的数据集是:

任务 文档 查询 相关配对 平均文档长度 最大文档长度 平均查询长度
NanoHotpotQA 5,090 50 100 57.3 345 14.9
NanoSciFact 2,919 50 56 205.8 1524 13.5
NanoArguAna 3,635 50 50 164.5 1058 193.0
NanoNFCorpus 2,953 50 2,518 223.3 1460 3.3
NanoFiQA2018 4,598 50 123 159.1 1882 10.2

我们使用了我们自定义构建的 llama-embedding 进行基准测试。

tag量化质量

表现最佳的量化版本是 IQ3_M (3.84 BPW) - 低于 2 位的量化效果比 v3 差,因此使用它们的意义不大。

Quantization NanoHotpotQA NanoFiQA2018 NanoArguAna NanoNFCorpus NanoSciFact
IQ1_S 0.6369 0.3178 0.3798 0.2933 0.5934
IQ1_M 0.6316 0.3313 0.5167 0.3256 0.6114
IQ2_XXS 0.7236 0.4582 0.4584 0.4067 0.7392
IQ2_M 0.7427 0.5869 0.5090 0.4468 0.7880
Q2_K 0.7683 0.5744 0.5168 0.4183 0.7546
IQ3_XXS 0.7780 0.5991 0.4811 0.4267 0.7610
IQ3_XS 0.7727 0.5615 0.5195 0.4439 0.7726
IQ3_S 0.8002 0.5505 0.4886 0.4381 0.7690
IQ3_M 0.8106 0.5387 0.5091 0.4462 0.7760
Q3_K_M 0.7567 0.5267 0.4486 0.4092 0.7775
IQ4_NL 0.7930 0.5598 0.4911 0.4285 0.7794
IQ4_XS 0.7979 0.5627 0.4947 0.4258 0.7789
Q4_K_M 0.8029 0.5569 0.4883 0.4226 0.7877
Q5_K_S 0.7969 0.5581 0.4721 0.4288 0.7842
Q5_K_M 0.7927 0.5601 0.4745 0.4247 0.7873
Q6_K 0.7951 0.5636 0.4822 0.4337 0.7846
Q8_0 0.7938 0.5687 0.4784 0.4335 0.7851
F16 0.7940 0.5610 0.4931 0.4343 0.7963
v3 (Transformers) 0.7393 0.5144 0.4600 0.4068 0.7820
v4 (Transformers) 0.7977 0.5571 0.4844 0.4351 0.7963

tag速度和 VRAM

现在我们将基准数据集固定为 NanoHotpotQA,并绘制所有量化模型,以其每权重比特数与速度(以每秒词元数衡量)和 VRAM 消耗进行对比。我们发现 GGUF 版本在 FP16 下比原始版本略快(2023 个词元/秒 vs 1865 个词元/秒)。大多数量化模型聚集在 2000-2100 个词元/秒附近。启用闪存注意力后,所有量化模型的速度提升了约 77%(3000+ 个词元/秒 vs 2000+ 个词元/秒)。然而,性能最佳的量化模型 Q8_0 以约 3700 个词元/秒的速度,仍然远落后于原始 v3(572M 参数),后者达到了 16000 个词元/秒。量化版本节省了大量 VRAM,并且几乎达到了具有 IQ3 的 v3 FP16 模型的水平。

Quantization BPW File Size (GB) Peak VRAM (GB) Token/s w FA Token/s w/o FA
IQ1_S 2.04 0.73 4.04 3625 2050
IQ1_M 2.19 0.79 4.09 3349 1997
IQ2_XXS 2.44 0.88 4.19 3701 2071
IQ2_M 2.94 1.06 4.37 3407 1989
Q2_K 3.29 1.18 4.49 3173 1905
IQ3_XXS 3.31 1.19 4.50 3668 2067
IQ3_XS 3.59 1.29 4.60 3604 2053
IQ3_S 3.76 1.35 4.66 3599 2049
IQ3_M 3.84 1.38 4.69 3603 2053
Q3_K_M 4.11 1.48 4.78 3450 2008
IQ4_NL 4.72 1.69 5.00 3571 2039
IQ4_XS 4.49 1.61 4.92 3585 2046
Q4_K_M 4.99 1.79 5.10 3558 2045
Q5_K_S 5.61 2.02 5.32 3567 2044
Q5_K_M 5.75 2.07 5.38 3528 2034
Q6_K 6.56 2.36 5.66 3334 1981
Q8_0 8.50 3.05 6.36 3767 2101
F16 16.00 5.75 9.70 3399 2023
v3 (Transformers) 16.00 1.10 2.82 16505
v4 (Transformers) 16.00 7.40 14.45 1865

点击展开系统信息

load_tensors: 正在加载模型 tensors,这可能需要一段时间... (mmap = true)
load_tensors: 正在将 36 个重复层卸载到 GPU
load_tensors: 正在将输出层卸载到 GPU
load_tensors: 已将 37/37 层卸载到 GPU
load_tensors: CUDA0 模型缓冲区大小 = 3127.61 MiB
load_tensors: CPU_Mapped 模型缓冲区大小 = 315.30 MiB
...................................................................................
llama_context: 正在构建 llama_context
llama_context: n_seq_max = 1
llama_context: n_ctx = 4096
llama_context: n_ctx_per_seq = 4096
llama_context: n_batch = 4096
llama_context: n_ubatch = 4096
llama_context: causal_attn = 1
llama_context: flash_attn = 1 // 表中使用 FA 时为 1;不使用 FA 时为 0
llama_context: kv_unified = true
llama_context: freq_base = 1000000.0
llama_context: freq_scale = 1
llama_context: n_ctx_per_seq (4096) < n_ctx_train (128000) -- 将不会利用模型的全部容量
llama_context: CUDA_Host 输出缓冲区大小 = 0.59 MiB
llama_kv_cache_unified: CUDA0 KV 缓冲区大小 = 144.00 MiB
llama_kv_cache_unified: size = 144.00 MiB ( 4096 个单元格, 36 层, 1/1 个 seqs), K (f16): 72.00 MiB, V (f16): 72.00 MiB
llama_context: CUDA0 计算缓冲区大小 = 2470.16 MiB
llama_context: CUDA_Host 计算缓冲区大小 = 96.17 MiB
llama_context: graph nodes = 1234
llama_context: graph splits = 2
common_init_from_params: added <|endoftext|> logit bias = -inf
common_init_from_params: added <|im_end|> logit bias = -inf
common_init_from_params: added <|fim_pad|> logit bias = -inf
common_init_from_params: added <|repo_name|> logit bias = -inf
common_init_from_params: added <|file_sep|> logit bias = -inf
common_init_from_params: setting dry_penalty_last_n to ctx_size = 4096
common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable)

system_info: n_threads = 4 (n_threads_batch = 4) / 8 | CUDA : ARCHS = 890 | USE_GRAPHS = 1 | PEER_MAX_BATCH_SIZE = 128 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | BMI2 = 1 | AVX512 = 1 | AVX512_VNNI = 1 | LLAMAFILE = 1 | OPENMP = 1 | REPACK = 1 |
main: n_tokens in batch = 0
main: number of embeddings = 5090

tag最佳物理批次大小和上下文大小

我们现在将量化类型固定为 IQ3_S,并检查物理批次大小 (-ub) 和上下文大小 (-c) 如何影响速度和 VRAM。L4 GPU 上的结果表明,-ub=512 和 -c=2048 提供了最佳配置,在消耗 2,025MB VRAM 的同时,实现了每秒 4,143 个词元的速度。结论是直观的:当您知道输入中单个文档的最大长度时,使用刚好足以覆盖它的较小上下文大小。对于物理批次大小,512 个词元似乎是 L4 GPU 上的最佳选择。

每秒词元性能

ubatch_size ctx_size=64 ctx_size=128 ctx_size=256 ctx_size=512
64 2233 2093 2128 2125
128 N/A 2866 2821 2877
256 N/A N/A 3287 3349
512 N/A N/A N/A 3469
ubatch_size ctx_size=2048 ctx_size=4096 ctx_size=8192 ctx_size=16384
256 3971 3630 3593 2766
512 4143 3797 3758 2852
1024 4059 3742 3707 2822
2048 3957 3631 3603 2762
4096 N/A 3450 3410 2625

峰值 VRAM 使用量 (MB)

ubatch_size ctx_size=64 ctx_size=128 ctx_size=256 ctx_size=512
64 1691 1689 1689 1697
128 N/A 1729 1727 1737
256 N/A N/A 1803 1811
512 N/A N/A N/A 1963
ubatch_size ctx_size=2048 ctx_size=4096 ctx_size=8192 ctx_size=16384
256 1885 1947 2099 2409
512 2025 2101 2257 2577
1024 2329 2407 2571 2917
2048 2933 3025 3203 3597
4096 N/A 4285 4497 4985

tag结论

对于希望在经济型 GPU 上高效运行量化 GGUF 的 v4 用户,请选择 IQ3_S 或 IQ3_M 以及我们的自定义构建的 llama-embedding - 这应该在常规数据集(句子长度小于 2048 个词元)上为您提供每秒 4000 个词元的速度。对于嵌入更长的文档,增加上下文大小 -c 并控制物理批次大小 -ub 以减少 VRAM 占用。使用我们的自定义构建,您可以通过将 -ub 设置为一个较小的数字(如 1024)来编码超长文档(>32K 词元),这在原始实现或 vanilla transformers 中是不可能的。

对速度优化的追求永无止境。始终存在更快、更精简且具有更高吞吐量的实现空间。每秒 4000 个词元可能不是我们的上限 - 还有很多工作要做。除了修复 llama.cpp 中的 qwen2.5-vl-3b mmproj/视觉transformer实现之外,我们还在探索更深层次的 llama.graph 和 KV 缓存级别的优化,改进 llama-serving 批处理逻辑,并向嵌入 API 添加流式传输选项。我们的目标是使 llama.cpp 原生支持现代的仅解码器多模态向量模型,以用于我们当前和未来的重排器版本。

类别:
技术博客
rss_feed

更多新闻
三月 11, 2026 • 7 分钟的读取量
从多模态大模型中引导音频向量模型
Han Xiao
Abstract illustration of a sound wave or heartbeat, formed by blue, orange, and gray dots on a white background.
三月 06, 2026 • 6 分钟的读取量
通过原始数值识别向量模型
Han Xiao
Fingerprint illustration made from numbers, showcasing digital and high-tech design on a light background.
九月 09, 2025 • 11 分钟的读取量
Llama.cpp 和 GGUF 中的多模态向量模型
Andrei Ungureanu
Alex C-G
Cartoon llama in the center of a white background, emitting laser-like beams from its eyes. The illustration creates a playfu
办公室
location_on
加利福尼亚州桑尼维尔
710 Lakeway Dr, Ste 200, 桑尼维尔, 加州 94085, 美国
location_on
德国柏林
Prinzessinnenstraße 19-20,10969 柏林,德国
搜索底座
读取器
向量模型
重排器
获取 Jina API 密钥
速率限制
API 状态
公司
关于我们
联系销售
新闻
实习生项目
下载 Jina 标志
open_in_new
下载 Elastic 徽标
open_in_new
条款
安全
条款及条件
隐私
管理 Cookie
email
Elastic Jina AI © 2020-2026.