大模型分不清 9.9 与 9.11 谁大,那 Embedding 模型呢?
在维也纳举办的ICML会议茶歇期间,一位Jina用户抛出了一个近期在LLM社区引起热议的问题:我们的Jina Embedding模型能不能判断9.11比9.9更小?不少大模型都在这道“送分题”上翻了车。
实话实说,当时我也没法立刻给出肯定的答案。但这个问题让他耿耿于怀,他推测Tokenizer可能是症结所在。这想法立刻触动了我的实验神经——干脆动手测一测,用数据说话。
本文通过一系列实验,系统评估Embedding和Reranker模型在数字比较上的真实能力。为了贴近实际应用场景,我设计了几类有挑战性的测试用例:
- 小数比较(例如0.001和0.0001)
- 货币金额($1.99和$2.00)
- 日期比较(例如2023-12-31和2024-01-01)
- 时间比较(例如23:59和00:00)
实验中选用了jina-embeddings-v2-base-en(2023年10月发布)和jina-reranker-v2-multilingual(2024年6月发布)两个模型,分别观察它们在数字理解方面的表现和短板。话不多说,直接看结果。
实验装置
完整的实现代码可以在下面的Colab中查看:https://colab.research.google.com/drive/11kUxYhHMLqYhw5HVKEYdHv0EfdZIyBBy
实验设计非常直观。以检查Embedding模型是否理解1到100之间的数字为例:
- 构建文档:为每个数字生成对应的字符串文档。
- 发送至Embedding API:获取每个文档的嵌入向量。
- 计算余弦相似度:计算每两个文档之间的余弦相似度,形成一个相似度矩阵。
- 绘制散点图:矩阵中每个元素(i, j)映射为一个点,X轴为(i-j)的差值,Y轴为相似度值。
核心逻辑是:如果差值(i-j)为零,说明i等于j,语义相似度应该最高;随着差值增大,相似度应逐步下降。
理想情况下,相似度与差值呈线性关系。
Reranker模型的流程类似,区别在于:我们把每个文档依次当作查询,加上Prompt“哪一项最接近...”,将所有其他文档作为候选进行排序。Reranker API返回的相关性得分直接作为语义相似度度量。核心实现代码如下:
def rerank_documents(documents):
reranker_url = "https://api.jina.ai/v1/rerank"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 初始化相似度矩阵
similarity_matrix = np.zeros((len(documents), len(documents)))
for idx, d in enumerate(documents):
payload = {
"model": "jina-reranker-v2-base-multilingual",
"query": f"what is the closest item to {d}?",
"top_n": len(documents),
"documents": documents
}
...
模型能否比较1到100之间的数字?
左侧是jina-embeddings-v2-base-en的结果,右侧是jina-reranker-v2-multilingual的结果。

如何阅读这些图
在继续解读结果之前,先说明一下怎么看这些散点图。
首先,Embedding模型表现不错,而Reranker模型稍逊一筹。
X轴代表索引差值(i-j),范围是[-100, 100]。由于文档集按顺序排列,|i-j|越小,两个文档在语义上越接近;差值越大,相似度越低。所以你会看到相似度(Y轴)在X=0处达到峰值,然后随着X绝对值增大而线性下降。
理想形态应该是一个尖峰或“^”形状。
青色趋势线显示了每个X值的平均相似度及其标准差。由于文档集是均匀分布的,连续文档间的间隔相等,理论上相似度应该线性下降。
Embedding模型的图总是对称的
相反,Reranker模型的图总是非对称的
模型能否比较-100到-1之间的负数?
测试负数空间中的语义相似性。数据集为从-1到-100的负整数字符串:documents = [str(-i) for i in range(1, 101)]。下图显示散点图及均值、标准差。
左侧是Embedding模型,右侧是Reranker模型。

模型能否比较更大间隔的数字:1000, 2000, ..., 100000?
测试间隔为1000的数字序列。documents = [str(i*1000) for i in range(1, 101)]。同上,散点图包含均值和标准差。
左侧是Embedding模型,右侧是Reranker模型。

模型能否比较任意范围内的数字,例如376, 377, ..., 476?
测试偏移后的范围:documents = [str(i+375) for i in range(1, 101)]。
左侧是Embedding模型,右侧是Reranker模型。
模型能否比较非常大的数字:4294967296, 4294967297, ..., 4294967396?
测试大数字范围:documents = [str(i+4294967296) for i in range(1, 101)]。
左侧是Embedding模型,右侧是Reranker模型。

模型能否比较0.0001, 0.0002, ..., 0.1之间的浮点数?(不固定小数位数)
测试浮点数:documents = [str(i/1000) for i in range(1, 101)]。
左侧是Embedding模型,右侧是Reranker模型。

模型能否比较货币金额:$1, $2, ..., $100?
测试货币格式:documents = ['$'+str(i) for i in range(1, 101)]。
模型能否比较日期:2024-07-24, 2024-07-25, ..., 2024-10-31?
测试日期格式:today = datetime.today(); documents = [(today + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(100)]。
模型能否比较时间:19:00:07, 19:00:08, ..., 20:39:07?
测试时间格式:now = datetime.now(); documents = [(now + timedelta(minutes=i)).strftime('%H:%M:%S') for i in range(100)]。
观察结果
从上述图表中可以总结出以下要点:
Reranker模型
- ,即便是在1到100这样简单的数字范围内,表现也不理想。
Reranker模型在处理数字比较时确实力不从心
- 不过,测试中我们为Reranker构造了特殊提示词“最接近x的一项是什么”,这也可能对结果产生了影响。
Embedding模型
- Embedding模型在处理1到100的小数字或-100到-1的负数时表现尚可,但一旦数字范围扩大或涉及浮点数等复杂数值区间,效果就大打折扣。
- 还可以注意到,每隔10的倍数处,算法表现会出现规律性波动。
这很可能与分词器将字符串如"10"拆分成"1"和"0"的方式有关。
日期和时间理解
- ,大多数情况下都能准确比较。例如在日期图表中,每30或31天会出现一个高峰(对应一个月天数);在时间图表中,每60分钟也出现一个高峰(对应一小时分钟数)。
Embedding模型对日期和时间有相当不错的理解
- Reranker模型也在一定程度上捕捉到了这种理解。
可视化与“零”的相似性
我们还设计了一个直观有趣的实验:可视化任意数字与零(原点)之间的语义相似性。固定参考点为0的嵌入,观察数字与0之间的相似度是否随数字增大而线性下降。
Google Colab:https://colab.research.google.com/drive/1S9qZQ0jjdKLNUT2GKqPbU4ogpDe6g9Qh
将查询固定为"0"或"与数字零最接近的数字是什么",对所有数字排序,观察相关性得分是否随数字递增而下降。结果如下:
左侧是Embedding模型,右侧是Reranker模型。
关键发现
虽然实验设置相对简单,但结果揭示了当前模型在数字处理方面的几个基本问题,为后续模型开发提供了宝贵方向。
影响模型数字比较能力的两大关键因素是
分词策略
训练数据
首先是分词策略:
来源:HuggingFace上的Tokenizer Playground。
其次是训练数据:
密集检索模型(如Embedding和Reranker)的算术能力,对于涉及RAG以及高级检索和推理的任务至关重要。强大的数字推理能力可以显著提升搜索质量,尤其是在处理JSON这类结构化数据时。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名