跳到正文
Hacker News· karimtn·· 10 天前AI 评分22

EmbeddingGemma-2 的 jeffhub 用例移植:CPU 上的检索与分类基准

Embedding Gemma2 Use Cases

AI 导读

开发者将 jeffhub.ai 的四个用例移植到 Google 的 EmbeddingGemma-2 嵌入模型上,用 768 维嵌入加余弦相似度替代原 0.8B decider 模型,并附可运行 demo 与延迟、质量基准。

正文 · AI 翻译

Gemma2-jev — jeffhub 在 EmbeddingGemma-2 上的用例

作者: Med Karim Bchini @karimtn

将 jeffhub.ai 的用例移植到 Google 的 EmbeddingGemma-2 嵌入模型上,附带可运行的演示以及延迟 + 质量性能基准测试。

jeffhub 提供一个 0.8B 的“System 1”决策模型,外加每个任务一个小型适配器;每个适配器接收一个输入和一组选项,并为每个选项返回一个概率。本项目保留这种请求形态(“从你的选项中选一个,并给出概率”),但将 0.8B 决策模型替换为 EmbeddingGemma-2 嵌入:每个选项通过与少量带标签的示例的余弦相似度(分类)或通过稠密段落排序(检索)来打分,再用 softmax 将分数转换为概率。

已实现的用例

jeffhub 适配器 类别 在此移植为 质量指标
ground 检索 稠密段落检索 / 重排序 Recall@1、Recall@5、MRR
support-intents 支持 最近示例意图分类 准确率、macro-F1
spam 安全 正常 / 垃圾邮件 / 钓鱼分类 准确率、macro-F1
triage 支持 工单路由到团队 准确率、macro-F1

环境及为何选择此技术栈

此处的运行环境没有 Python、没有 GPU,且磁盘预算很小,因此示例使用:

  • Node.js + @huggingface/transformers v4(ONNX Runtime,CPU)。
  • onnx-community/embeddinggemma-2-ONNX 采用 int8(dtype: "q8" → model_quantized.onnx,约 314 MB)。

EmbeddingGemma-2 是一个 740M 参数的模型(270M 文本主干),将文本映射到统一的 768 维空间。它是任务引导的:一个简短的指令前缀告诉它要生成什么表示。此处使用的前缀直接来自模型卡:

用途 前缀
检索查询 task: search result | query:
文档 title: none | text:
分类 task: classification | query:

设置

npm install          # installs transformers.js + onnxruntime-node
npm run demo         # runs every use case on sample inputs
npm run bench        # latency + quality benchmark (writes bench/results.json)
npm run bench:quick  # smaller timing loops

首次运行会将 ONNX 权重(约 850 MB,全部三个编码器)下载到 ./models/,该目录已被 git 忽略。后续运行从磁盘加载约需 1–2 秒(页面缓存已预热)。

项目结构

src/model.js       EmbeddingGemma-2 loader, task prefixes, mean pooling, MRL truncation
src/knn.js         nearest-exemplar classifier -> per-option probabilities (softmax)
src/similarity.js  cosine / dot / softmax / ranking helpers
src/metrics.js     accuracy, macro-F1, Recall@k, MRR, percentile
src/usecases.js    the four use cases (ground, support-intents, spam, triage)
src/index.js       public re-exports
data/*.json        small labelled datasets (train exemplars + held-out test)
examples/demo.js   runnable end-to-end example
bench/perf.js      latency + throughput + quality harness

示例输出(npm run demo)

jeffhub use case: ground  (Retrieval — pick the passage that answers)
Q: Which planet is known as the Red Planet?
  1. [0.8068] d1  Mars, known for its reddish appearance, is often referred to as ...
  2. [0.7056] d3  Jupiter is the largest planet in the solar system, with a ...
  3. [0.6650] d2  Venus is often called Earth's twin because of its similar size ...

jeffhub use case: spam
Input: Your account has been suspended, verify your password immediately at the link below.
  -> phishing  (confidence 99.7%)
     options: phishing=99.7%  spam=0.2%  legitimate=0.1%

基准测试结果

在本机测量(仅 CPU、int8、单进程)。数值会随机器负载在每次运行间略有波动。

Embedding latency (batch = 1)
  p50 168 ms | p95 177 ms | mean 168 ms   (n=30)

Embedding throughput (batched)
  24 docs/s   (128 docs in 5.36 s, 41.8 ms/doc)

Per-use-case quality + end-to-end latency
  use case          | n  | quality                                   | p50 ms | p95 ms
  ------------------+----+-------------------------------------------+--------+-------
  ground            | 17 | Recall@1 100.0% | Recall@5 100.0% | MRR 1.000 |  166.9 |  171.5
  support-intents   | 13 | accuracy 100.0% | macro-F1 100.0%         |  184.0 |  233.2
  spam              | 13 | accuracy 100.0% | macro-F1 100.0%         |  170.7 |  185.2
  triage            | 12 | accuracy 100.0% | macro-F1 100.0%         |  163.6 |  169.2

如何诚实地解读这些数据:

  • 延迟/吞吐量是这里真正有意义的性能数字:在 CPU 上单条文本嵌入约 170 毫秒,批量约 24 文档/秒。这就是在没有 GPU 的 CPU 上运行 740M 模型的代价。
  • 质量达到上限(100%)是因为数据集规模小且经过精心整理,且留出集的行是示例的改写。这表明移植可以端到端运行;这并非一个有竞争力的准确率声明。严谨的声明需要真实的带标签基准(例如 MTEB 检索子集或真实支持工单)。

关于方法的说明

  • 池化 / 归一化:均值池化,L2 归一化,因此点积 == 余弦。
  • 分类:每个选项由其最近的带标签示例(余弦)打分,然后 softmax(温度 0.05)得出 jeffhub 返回的每个选项的概率。
  • 检索:文档使用文档前缀嵌入,查询使用检索查询前缀嵌入,然后按余弦排序。
  • Matryoshka(MRL):embed(texts, { dim: 256 }) 截断到 128/256/512 维并重新归一化,以略微牺牲质量为代价换取 3–6 倍更小的向量存储。

局限性

  • 此处没有 GPU,因此吞吐量受限于 CPU;通过将 device: "webgpu" 传给 loadModel,同样的代码可在 WebGPU 上运行。
  • ONNX 构建会加载全部三个编码器(文本 + 视觉 + 音频)。仅文本部署可以只提供 onnx/model_quantized.* 以节省空间。
  • 数据集在设计上很小(它们位于 data/ 中),旨在演示流程,而非对模型进行基准测试。

来源:Hacker News · github.com