Embedding 实战:闭源 vs 开源

---
title: "Embedding 实战:闭源 vs 开源"
author: Ida Silfverskiöld
source_url: https://towardsdatascience.com/working-with-embeddings-closed-versus-open-source-39491f0b95c2/
published_at: 2024-09-26
fetched_at: 2026-05-28
language: zh
translator: Hermes
---

# Embedding 实战:闭源 vs 开源

### 做检索这件事

![先聚类,再做语义搜索 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1EaD1Iv5O6UX5EInQ09SYUA.png)

_如果你不是会员但想读这篇,[这是免费阅读链接](https://medium.com/@ilsilfverskiold/39491f0b95c2?source=friends_link&sk=d94cfe5675e1c8810edb5ecfaa86ebc0)。_

embedding 是 NLP 的基石之一。它能干的事不少,但最常见的一件就是检索场景里的语义搜索。

虽然整个圈子最近都在聊知识图谱检索 pipeline,但传统的向量检索其实并没过时。

网上能找到一堆文章讲怎么把语义搜索里不相关的结果过滤掉——这篇也会聊这个,用聚类和重排(re-ranking)这两招。

不过这篇**真正想做的事**,是**把开源和闭源 embedding 模型放一起对比**——还要看不同体量。

![本文要看的几个模型——市面上还有更多 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1PO0sRdIm0Cn6Ni6qd7nTrw.png)

我们会对比 9 个 embedding 模型,全是 MTEB [排行榜](https://huggingface.co/spaces/mteb/leaderboard)上排名靠前的。这样你大概能感觉到大模型 vs 小模型的差距,以及规模上去之后成本会怎么涨。

如果你用过 OpenAI 生成 embedding,估计也好奇过它到底竞争力够不够。

简单回顾一下 embedding——如果你刚接触:我们给每段文本生成 embedding(一组向量),就是把文本转成计算机能理解的东西。

![文本到 embedding | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1Wd7tjsy9DD7VcJ-gvxS4cA.png)

具体到语义搜索,我们是把不同文本的 embedding 拿来比,看它们语义上有多像。这样查询就可以走"模糊搜索"——按关系找,不是按关键词精确匹配。

![query embedding 跟其它 embedding 的语义相似度 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1A6iKvrJ0AT_ihKW7i8qyGQ.png)

引言里我会讲 embedding 怎么工作,重点是怎么算语义相似度。

我每写一篇都喜欢拿一个具体场景练手,这次也不例外。这个想法来自一位咨询公司老板——他问我能不能做一个应用,把岗位描述自动匹配到 LinkedIn profile。

如果真做生产用,肯定要上百万真实 profile,但这篇只是演示,我用合成数据做了 6,900 份 LinkedIn profile。

数据集在[这里](https://huggingface.co/datasets/ilsilfverskiold/linkedin_profiles_synthetic)。

这场景算简单的:profile 不需要切块(一份就一段),领域也不复杂——一眼就能看出模型有没有抓对关系。

但思路是通用的,可以套到类似问题上。

如果你想直接跳过引言、用 LinkedIn 数据集动手玩不同模型,往下翻就行。

## 引言

这篇里 profile 数量不多,可以把聚类当成一种无监督的分类方法用在整个数据集上。

下面是聚类长什么样的示意图。

![LinkedIn profile 分成 4 类的简化示意 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1GX0wryuRximX84j2ThNu5g.png)

聚类还能让我们看出不同模型怎么理解事物之间的关联。

看模型表现,我们可以先把正确的那一组隔离出来,再在簇内做语义搜索。

![把 query 匹到对的簇——简化图 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1jgPcJBsivyHiey2CC0hwEg.png)

这样能过滤掉不相关的结果,比如模型把 product manager 和 product marketing manager 搞混的情况。

最后还能加一步:用 LLM 做重排,确保最相关的结果排在最上面。

为了省事也省钱,我把每个待评测模型的 [embedding](https://huggingface.co/datasets/ilsilfverskiold/linkedin_recruitment_questions_embedded) 都已经预先算好放进[数据集](https://huggingface.co/datasets/ilsilfverskiold/linkedin_profiles_synthetic)里了,匿名岗位描述的 embedding 也算好了。

提醒一下:想直接动手可以跳到**用例**那一节,但成本那部分别跳过。

### Embedding

前面提过,embedding 是文本的数值表示,把含义编码下来——这样计算机就能处理和理解自然语言。

![文本到 embedding | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1Wd7tjsy9DD7VcJ-gvxS4cA.png)

到了 transformer 这一代模型,它们能理解整句的 context,从而抓住一个词或一句话的多重含义——这事几年前还做不到。

我们其实可以把 embedding 画在图上,当成几何空间里的点。embedding 之间的语义关系,就体现为几何上的远近。

![embedding 在图上是几何空间里的点 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1yZRLKWJAuM_wUrc2Yng4zg.png)

不同模型为不同任务训练,但稍大一些的模型一般都是通才,能干**检索**、**聚类**、**分类**这类活。

**语义搜索**用在检索里——它就是用图上的"近"来判断 query 应该匹到哪些 embedding,本质上是在算图上 embedding 之间的距离。

要在语义搜索里算 embedding 之间的相似度有好几种方法,但最常用的是余弦相似度。

![用语义相似度找最佳匹配 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1AKzbU9zGhFQjv020QLwtfQ.png)

你选哪个模型,直接决定语义搜索的结果——这归根结底取决于它是怎么训练的。

训练用的数据集、目标、架构都很关键,会直接影响模型对各种文本的理解和关联能力。

**聚类**则不太一样——它是把数据组织成一组组(簇),让同一簇内的相似度高于跨簇相似度。聚类更擅长把 embedding 之间的相似关系挖出来,让我们能干净地隔离出某一组。

![把 embedding 聚类好把相似 profile 分组,并把 query 落位 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/18-Yon9-z2rYxHSocv2J32g.png)

这一步让我们能在做语义搜索之前先过滤掉不相关的匹配——相当于一道降噪工序。

起码思路是这样。

不是每个模型都能按我们想要的方式做聚类。有的擅长,有的拉胯,全看它怎么训出来的。

### Embedding 模型

那怎么知道选哪个?这时候 [MTEB](https://huggingface.co/spaces/mteb/leaderboard) 排行榜就该出场了——它按各种任务上的表现给 embedding 模型排名。

我从中挑了几个出来对比:OpenAI 那几款用得多的,再加一个 fine-tune 过的 Mistral-7B,还有更小更新的模型比如 Mixedbread AI 的 [Mxbai](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1)。

差不多都是过去两年里发布的。

![本文要用的模型——这份名单不算定稿 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1u0MZhkT__YnGxrbOIgAPLw.png)

如果你刚接触开源模型,可能会惊讶——好多开源模型其实排得很靠前。如果你已经玩过这些模型,看一眼哪个在这个任务上跑得最好也挺有意思。

下面这张表列了每个模型的体量、最大 token 数、以及检索和聚类的排名。

![本文要用的几个模型在 MTEB 排行榜的指标 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1pOTsw0SD6Viu3VTTiduEBQ.png)

很多人都用过 OpenAI 的 [Ada-002](https://openai.com/index/new-and-improved-embedding-model/),它在我们的列表里垫底。不过 OpenAI 后来出了 text-embed-3 的 small 和 large 两版——表现更好,价格也更便宜。

那你可能会问:开源模型在排行榜上排得这么高,干嘛还有人用商业模型?

### 开源模型的成本账

用开源模型听起来挺好的,隐私上也是首选。排行榜上靠前的不少,但你得算一笔账:自己托管 vs 调 API,到底哪个划算。

我看了一下成本——把小一些(约 350M)和大一些(7B)的开源模型放 GPU 上自托管,对比按 token 付费的几款主流商业模型。

![1 万、10 万、100 万、250 万条文本的算力成本——不含存储 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/17hfGw46eFfgXoZyFOy_abw.png)

*前提是每段文本 400 token——这样 334M 模型在单张 L4 GPU 上每秒能处理 75–90 段,7B 模型在单张 A100 上每秒约 30–40 段(也可能更多)。*

你会发现:一旦要 embed 几百万段文本,text-embed-3-large 或 ada-002 这种模型成本就会飙——而且这还没算存储。

如果你是企业客户,又在看 Nvidia 的 embedding 模型比如 nv-embed-v1,他们的 [API](https://build.nvidia.com/nvidia/nv-embed-v1) 挺好用的——我用它测过几个模型。

不过用小模型(500M 以下)肯定是最稳的选择。能上小一点的开源模型就上——算力成本能直接砍掉 90%。

我也算了一下小模型和大模型放单张 GPU 上要跑多久。

![单张 GPU 估算的处理时间 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/12CV87bSuq-Cw4aseuXW-7g.png)

调 API 也要花时间,而且有推理速率限制——所以不管选哪条路,都要算把整份数据集 embed 完要多久。

开源模型嘛,可以多堆几张 GPU。但这至少给你点感觉——选小一点的可能更省电。

不过测几个看看哪个适合你的任务总没错——接下来就这么干。

### 量化

上面看到了,7B 这种规模的大模型还是又贵又费电。我们只算了 250 万条 embedding 的成本——一旦再往上 scale,[量化](https://huggingface.co/blog/embedding-quantization)就值得看一看了。

量化是用更少的位数表示模型的数据,从而把模型压小。思路是:用 4-bit、8-bit 这类量化手段,让原本带不动大模型的硬件也能跑起来。

也有几个人测过量化对各种指标的影响——我最近看到的一篇说整体性能下降约 12%。

这个以后我得专门写一篇——这种"经济性 vs 性能损失"的话题我特别喜欢挖。

## 用例

我不知道你怎么样——反正我喜欢直接拿不同模型测一测,而不是只看指标。这样我能直观感受到:小模型和大模型在文本关系上理解力差多少。

合成 LinkedIn profile [数据集](https://huggingface.co/datasets/ilsilfverskiold/linkedin_recruitment_questions_embedded)在[这里](https://huggingface.co/datasets/ilsilfverskiold/linkedin_profiles_synthetic),要匹配的岗位描述数据集也在。

要用的 Colab notebook 在[这里](https://colab.research.google.com/gist/ilsilfverskiold/4214061d3ffd64479067e6e0dded3ffc/visualize_different_embedding_models.ipynb)。

### 导入数据

要跟着做就得打开那个 [notebook](https://colab.research.google.com/gist/ilsilfverskiold/4214061d3ffd64479067e6e0dded3ffc/visualize_different_embedding_models.ipynb)——打开后你会看到我们从 Hugging Face 拉了两个数据集。

```python
# 带 embedding 的合成 LinkedIn profile
dataset = load_dataset("ilsilfverskiold/linkedin_profiles_synthetic")
profiles = dataset['train']
# 带 embedding 的匿名岗位描述
dataset = load_dataset("ilsilfverskiold/linkedin_recruitment_questions_embedded")
applications = dataset['train']
```

这两个数据集让我们能在 6,900 份合成 LinkedIn profile 上对比不同 embedding 模型。

合成数据嘛,毕竟是合成的,要打折听。这批是 Llama 3.1 生成的——而且确实有点"过度对齐"的味道:profile 里反复出现 "results-driven"、"seasoned"、"dedicated" 这种词。

embedding 已经预先算好放进 `profiles` 里了——你点进去就能看到。

```python
# profiles 数据集
Dataset({
    features: [...,'embeddings_nv-embed-v1', 'embeddings_nv-embedqa-e5-v5', 'embeddings_bge-m3', 'embeddings_arctic-embed-l', 'embeddings_mistral-7b-v2', 'embeddings_gte-large-en-v1.5', 'embeddings_text-embedding-ada-002', 'embeddings_text-embedding-3-small', 'embeddings_voyage-3', 'embeddings_mxbai-embed-large-v1 '],
    num_rows: 6904
})
```

_P.S. embeddings_gte-large-en-v1.5 这个跑不通——我尝试过自己托管但没把所有 embedding 都跑齐,所以别用它。_

接下来你需要选一份要匹配的岗位描述。

看下面代码——我选了第 2 份,你可以换别的编号。

```python
application = applications[1] # 选第 2 份——一个 product marketing manager 岗位
application_text = application['natural_language']
print("application we're looking for: ", application_text)
```

懒得跑代码也行,直接在 Hugging Face 上看[数据集](https://huggingface.co/datasets/ilsilfverskiold/linkedin_recruitment_questions_embedded)。

![Hugging Face 上的岗位描述数据集预览 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1n9OBolBh6iS25euugU7D-w.png)

这一步你可以挑想用的 embedding 模型。我大部分都试过了,这次用 `embeddings_mxbai-embed-large-v1`。

这是一个 334M 的开源模型——在前面那张表里它的检索和聚类排名都挺靠前。

想换别的模型只要改一下名字就行。看上面那个[数据集](https://huggingface.co/datasets/ilsilfverskiold/linkedin_profiles_synthetic)就知道有哪些选项。

```python
# 拿这个 embedding 模型对应的 query embedding——这里挑的是 mxbai-embed-large-v1
query_embedding_vector = np.array(application['embeddings_mxbai-embed-large-v1'])
embeddings_list = [np.array(emb) for emb in profiles['embeddings_mxbai-embed-large-v1 ']] # 注意这里多了个空格
texts = profiles['text']
```

### 语义搜索

我们先不上聚类,直接做一次语义搜索——看看裸跑能到什么效果。

要算 profile 跟 query(也就是岗位描述)之间的语义相似度,跑下面这段代码。

```python
# 先单独算一下余弦相似度(不带聚类)
def cosine_similarity(a, b):
    a = np.array(a)
    b = np.array(b)
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

similarities = []
for idx, emb in enumerate(embeddings_list):
    sim = cosine_similarity(query_embedding_vector, emb)
    similarities.append(sim)
```

然后按相似度从高到低排序,显示前 30 条。

```python
results = list(zip(range(1, len(texts) + 1), similarities, texts))
sorted_results = sorted(results, key=lambda x: x[1], reverse=True)
# 把结果打出来
print("\nSimilarity Results (sorted from highest to lowest):")
for idx, sim, text in sorted_results[:30]: # 想看更多就调这里
    percentage = (sim + 1) / 2 * 100
    text_preview = ' '.join(text.split()[:10])
    print(f"Text {idx} similarity: {percentage:.2f}% - Preview: {text_preview}...")
```

结果大概长这样——具体看你选的是哪一份岗位描述。

```text
Similarity Results (sorted from highest to lowest):
Text 3615 similarity: 89.59% - Preview: Product Marketing Manager | Building Go-to-Market Strategies for Growth Results-driven...
Text 6299 similarity: 89.56% - Preview: Product Marketing Manager | Driving Growth & Customer Engagement Results-driven...
Text 3232 similarity: 89.09% - Preview: Product Marketing Manager | Driving Product Growth through Data-Driven Strategies...
Text 5959 similarity: 88.90% - Preview: Product Marketing Manager | Data-Driven Growth Expert Results-driven Product Marketing...
Text 5635 similarity: 88.84% - Preview: Product Marketing Manager | Driving Growth through Data-Driven Marketing Strategies...
Text 5835 similarity: 88.74% - Preview: Product Marketing Manager | Cloud-Based SaaS Results-driven Product Marketing Manager...
Text 139 similarity: 88.66% - Preview: Product Marketing Manager | Scaling Growth through Data-Driven Strategies Experienced...
Text 6688 similarity: 88.48% - Preview: Product Marketing Manager | Driving Business Growth through Data-Driven Insights...
Text 6405 similarity: 88.27% - Preview: Product Marketing Manager | Scaling SaaS Products for Global Markets...
Text 3439 similarity: 88.11% - Preview: Product Manager | Focused on delivering innovative products that drive...
Text 5958 similarity: 88.00% - Preview: Product Manager Office | Growth Driven by Customer Centricity Highly...
Text 5183 similarity: 87.86% - Preview: Product Marketing Manager | B2B SaaS Experienced Product Marketing Manager...
Text 1329 similarity: 87.81% - Preview: Product Marketing Manager | Scaling Growth for Emerging Tech Startups...
Text 130 similarity: 87.81% - Preview: Product Marketing Manager | Growth Strategies & Launches Results-driven Product...
Text 3423 similarity: 87.78% - Preview: Product Marketing Manager | Scaling B2B SaaS Solutions Experienced Product...
Text 4234 similarity: 87.72% - Preview: Product Manager | Leading Cross-Functional Teams to Drive Business Growth...
```

mxbai 这个模型——还有不少其他模型也一样——明显能看出它把 product marketing manager 跟 product manager 一起返回了,这不是我们想要的。

*看上面 88.11% – Preview: Product Manager 和 88.00% – Preview: Product Manager Office 这两条。*

那就上聚类——看看它能不能帮上忙。

### 聚类

第一步从 profile 的 embedding 里搭聚类——你得先决定要分多少簇。

我选了 10。

```python
embeddings_array = np.array(embeddings_list)
num_clusters = 10 # 这里数字可以换
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
kmeans.fit(embeddings_array)
cluster_labels = kmeans.labels_

pca = PCA(n_components=2)
reduced_embeddings = pca.fit_transform(embeddings_array)
```

接下来要看 query(岗位描述)落在哪一簇。

```python
# 看 query 落到哪个簇里
query_embedding_array = np.array(query_embedding_vector).reshape(1, -1)
reduced_query_embedding = pca.transform(query_embedding_array)
# 预测 query 应该归到哪一簇
query_cluster_label = kmeans.predict(query_embedding_array)[0]
print(f"The query belongs to cluster {query_cluster_label}")
```

然后我们可以把簇画在 2 维图上——记得这是降维后的结果,所以有些簇可能叠在一起。

![把 LinkedIn profile 聚类画出来 - 截自 Colab notebook](https://towardsdatascience.com/wp-content/uploads/2024/09/1x_FhyXPYlBGg7E4wjde1nw.png)

你可以鼠标悬停到不同 embedding 上看 profile 内容。

![看第 5 簇的 embedding - 截自 Colab notebook](https://towardsdatascience.com/wp-content/uploads/2024/09/1D66AsbrJm3EEpZFpTLVZqw.png)

也可以把 query(图里的 X)单独标出来,看模型把它判到哪一簇。

![把第 5 簇连同 query X 一起隔离出来 - 截自 Colab notebook](https://towardsdatascience.com/wp-content/uploads/2024/09/1X_g1mrtrFnS0rkUYXPrx8g.png)

可以清楚看到,模型把 marketing 相关的人都正确归到同一簇——SEO specialist 和 growth hacker 也在里面,但 Office Product Manager 和 Product Manager 都不在。

漂亮。

到这一步,我们可以把聚类和语义搜索两招拼起来用,效果会更好。

记得换不同模型试试看哪个效果更好——你会发现大模型在"把相似 profile 分到一组"这件事上按理说更强,但有些小模型也能跑得不错。

### 聚类 + 语义搜索

既然 query 能正确归到对的簇里,我们就可以把两招拼起来用。

```python
# 在正确的簇内做语义搜索
cluster_indices = np.where(cluster_labels == query_cluster_label)[0]
cluster_embeddings = embeddings_array[cluster_indices]
cluster_texts = [texts[i] for i in cluster_indices]

similarities_in_cluster = []
for idx, emb in zip(cluster_indices, cluster_embeddings):
    sim = cosine_similarity(query_embedding_vector, emb)
    similarities_in_cluster.append((idx, sim))

similarities_in_cluster.sort(key=lambda x: x[1], reverse=True)
top_n = 40 # 想看更多结果就调这个
top_matches = similarities_in_cluster[:top_n]

print(f"\nTop {top_n} similar texts in the same cluster as the query:")
for idx, sim in top_matches:
    percentage = (sim + 1) / 2 * 100
    text_preview = ' '.join(texts[idx].split()[:10])
    print(f"Text {idx+1} similarity: {percentage:.2f}% - Preview: {text_preview}...")
```

跑完上面这段就能看到——结果里 Product Manager 不见了,换成了 Marketing Manager 这类更对路的人选。

```text
Top 40 similar texts in the same cluster as the query:
Text 3615 similarity: 89.59% - Preview: Product Marketing Manager | Building Go-to-Market Strategies for Growth Results-driven...
Text 3232 similarity: 89.09% - Preview: Product Marketing Manager | Driving Product Growth through Data-Driven Strategies...
Text 5959 similarity: 88.90% - Preview: Product Marketing Manager | Data-Driven Growth Expert Results-driven Product Marketing...
Text 5635 similarity: 88.84% - Preview: Product Marketing Manager | Driving Growth through Data-Driven Marketing Strategies...
Text 5835 similarity: 88.74% - Preview: Product Marketing Manager | Cloud-Based SaaS Results-driven Product Marketing Manager...
Text 139 similarity: 88.66% - Preview: Product Marketing Manager | Scaling Growth through Data-Driven Strategies Experienced...
Text 6688 similarity: 88.48% - Preview: Product Marketing Manager | Driving Business Growth through Data-Driven Insights...
Text 6405 similarity: 88.27% - Preview: Product Marketing Manager | Scaling SaaS Products for Global Markets...
Text 5183 similarity: 87.86% - Preview: Product Marketing Manager | B2B SaaS Experienced Product Marketing Manager...
Text 1329 similarity: 87.81% - Preview: Product Marketing Manager | Scaling Growth for Emerging Tech Startups...
Text 130 similarity: 87.81% - Preview: Product Marketing Manager | Growth Strategies & Launches Results-driven Product...
Text 3423 similarity: 87.78% - Preview: Product Marketing Manager | Scaling B2B SaaS Solutions Experienced Product...
Text 5945 similarity: 87.63% - Preview: Marketing Manager | Driving Growth through Data-Driven Strategies Results-driven marketing...
Text 2664 similarity: 87.59% - Preview: Product Marketing Manager | Driving Growth & Innovation Results-driven Product...
Text 3368 similarity: 87.54% - Preview: Product Marketing Manager | Scaling Growth through Data-Driven Strategies Highly...
Text 5794 similarity: 87.48% - Preview: Product Marketing Manager | Driving Growth through Data-Driven Insights Results-driven...
Text 5685 similarity: 86.71% - Preview: Performance Marketing Manager | Driving Business Growth through Data-Driven Strategies...
Text 5818 similarity: 86.37% - Preview: Digital Marketing Manager | Driving Business Growth through Data-Driven Strategies...
```

真实生产场景里,最好在做语义搜索之前先对数据做一遍过滤和分类。

这一节的核心就是让你自己对比不同模型——尤其是小模型 vs 大模型——看你愿意为更快更便宜的推理牺牲多少质量。

别只是为了上大模型而上大模型,除非你真的需要。

想继续评估这些模型,可以用 [RAGAs](https://docs.ragas.io/en/stable/) 看看不同模型下检索应用的表现。

### 关于模型表现的几点观察

要测性能总得挑个标准——我选的是看模型能不能把 product manager 和 product marketing manager 分清楚。

大模型在不上聚类的时候,更容易直接给出对的结果——但所有模型一开始都没把这两个职位分干净。

Ada-002 因为体量大不少,不上聚类的裸跑也表现不错;OpenAI 那个更小更新的 text-embed-3-small 反而差一些。

![给一个岗位 profile 设我们自己的评测指标 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1Jf8FbFMlyBeb3sO7-uEqEQ.png)

不过有些模型连聚类都聚不对——具体来说,fine-tune 过的 7B Mistral 和 E5 这次没跑好。这可能跟它们怎么训出来有关。

剩下那些在这个具体岗位上表现差不多。

让我意外的是 [mxbai](https://huggingface.co/mixedbread-ai/mxbai-embed-large-v1)——只有 335M 居然这么能打。这恰好说明:简单任务上,大模型可能就是杀鸡用牛刀。

这只是针对这一件小事的评测——你自己的任务该看什么指标得自己定。

不过从这里可以继续往前走——比如再叠一层重排,把最好的结果挑给 LLM 评。

### 重排(Re-Ranking)

RAG pipeline 里要修正不相关结果的招数有不少,重排是其中一种。

重排说白了就是把结果重新排序,让相关的排到最上面。一种常见做法是 [Pairwise Ranking(成对排序)](https://arxiv.org/pdf/2306.17563)。

具体怎么做:把一对 profile 喂给一个模型(可以是 LLM),让它根据岗位描述判断哪一个更合适。

![用 LLM 做 Pairwise Ranking——简化图 | 图:作者](https://towardsdatascience.com/wp-content/uploads/2024/09/1cWGmCJxKEJAAXl8UynF18A.png)

具体到你的场景,得把几种方法组合起来才能跑得好。

如果你刚接触 embedding,希望这篇有点收获;如果不算新手,希望这次至少给你扒了点小模型 vs 大模型的成本账——开源闭源都聊到了。

至于更大的 LLM——闭源那边确实领先;但 embedding 模型这块不是这样。

就记一句:给小一些、算力更友好的模型一个机会。

❤