相关文章:RAG 增强与向量基础篇:继续搭建“模型 + 向量 + 会话 + 工具”协同底座
相关文章:零成本打造本地多引擎大模型与向量服务:Xinference 全栈部署 + 性能调优实战
面向真实长篇中文语料(《三国演义》《水浒传》《红楼梦》《西游记》)的 Embedding 模型 text2vec-base-chinese 和 bge-large-zh-v1.5 对比。聚焦:分块策略、批量嵌入性能、章节语义召回表现。全部结论基于本文给出的原始数据推导,无空谈路线。可直接复用测试框架加速你的 RAG / 语义检索选型。
1. 测试目标与方法概述
| 维度 | 说明 |
|---|---|
| 模型 | text2vec-base-chinese (dim=768) vs bge-large-zh-v1.5 (dim=1024) |
| 语料 | 四大名著(章节结构 + 默认窗口分块),章节识别均成功(无 fallback) |
| 两阶段 | Phase1: 嵌入性能 + 向量统计;Phase2: 章节粒度语义检索(Top1 / AvgTop5) |
| 指标 | totalMs / avgMs / p95Ms / normMean / normStd / Top1 / AvgTop5 |
| 采样 | 每模式前 sampleCap=3000(本次均未超限) |
| 查询集 | 每部 5 条“人物/事件/场景”复合关键词短语(共 20 条) |
| 检索方式 | brute force 逐章节向量余弦,对查询独立 embed(缓存章节向量) |
2. 分块策略简述(为什么看“章节 + 窗口”)
| 策略 | 目标 | 特点 |
|---|---|---|
| 章节模式 chapterOnly | 贴近原书结构、保留语义层级 | 长章节不做二次窗口拆分,强化“章节级检索”真实性 |
| 默认窗口模式 | 提供更细粒度召回 & 后续重排基础 | 超长章节二级切分 + overlap,提升长段命中概率 |
四部小说章节识别全部成功(chapterOnly chunks: 三国120 / 水浒120 / 红楼127 / 西游200),无需窗口回退,这使得章节粒度对比具有可比性。
3. Phase 1:嵌入性能结果(章节模式)
原始摘录(节选自评测报告 chapterOnly effective 集合):
| 模型 | 小说 | 章节数 (sample) | totalMs | avgMs | p95Ms | normMean | normStd |
|---|---|---|---|---|---|---|---|
| text2vec | 三国演义 | 120 | 6131 | 50.7 | 185.0 | 1.0000 | 0.0000 |
| text2vec | 水浒传 | 120 | 7160 | 59.1 | 193.0 | 1.0000 | 0.0000 |
| text2vec | 红楼梦 | 127 | 7026 | 54.8 | 186.0 | 1.0000 | 0.0000 |
| text2vec | 西游记 | 200 | 8691 | 42.9 | 183.0 | 1.0000 | 0.0000 |
| bge-large | 三国演义 | 120 | 15103 | 125.4 | 255.0 | 1.0000 | 0.0000 |
| bge-large | 水浒传 | 120 | 15639 | 129.8 | 259.0 | 1.0000 | 0.0000 |
| bge-large | 红楼梦 | 127 | 16199 | 127.1 | 261.0 | 1.0000 | 0.0000 |
| bge-large | 西游记 | 200 | 16557 | 82.3 | 188.0 | 1.0000 | 0.0000 |
3.1 速度差异量化
| 指标 | text2vec 四书均值 | bge 四书均值 | 差值 (bge - t2v) | bge ÷ text2vec | 结论 |
|---|---|---|---|---|---|
| avgMs | (50.7+59.1+54.8+42.9)/4=51.9 | (125.4+129.8+127.1+82.3)/4=116.2 | 64.3 | 2.24x | text2vec 平均耗时≈ bge 的 45% |
| p95Ms | (185+193+186+183)/4=186.8 | (255+259+261+188)/4=240.8 | 54.0 | 1.29x | text2vec 尾延迟显著更低 |
| totalMs 合计 | 6131+7160+7026+8691=29008 | 15103+15639+16199+16557=63498 | 34490 | 2.19x | 构建同语料 bge 总耗时约为 text2vec 2.2 倍 |
更严谨对 totalMs:
| 模型 | 四书 totalMs 合计 | 相对耗时比(相对于 text2vec) | 说明 |
|---|---|---|---|
| text2vec | 29008 | 1.00 | 章节级整体基建消耗低 |
| bge | 63498 | 2.19 | 大规模批量嵌入成本更高 |
观点:在章节粒度批量嵌入场景(例如“书籍/大部类知识入库”),text2vec 明显降低数据准备时间,适合作为向量底座快速构建模型;bge 更适合控制频率的小规模精排或增量补齐阶段。
3.2 normMean / normStd 现象
两模型所有章节 normStd=0.0000(四舍五入后),意味着:
- 向量已被内部归一化(或输出恒定范数层处理);
- 不能再依赖范数分布差异做异常检测。
观点:生产中需改用“随机向量样本余弦分布 + 服务端健康接口”监护,而非范数差异。
3.3 西游记上 bge avgMs 下降原因
bge 在前三部 avgMs ~125–130ms,西游记降到 82.3ms,可能成因:
- 西游记章节更短 / 分布更均衡 → 单次推理输入 token 更少;
- JVM / 模型后端缓存预热完成导致后段用时下降。需辅以“按文本长度桶统计”验证。
观点:做模型选型不能用单书“最优”数据套用于所有长文本;必须做长度分桶(<500 / 500–1000 / 1000+ 字)基线。
4. Phase 1:默认窗口模式(补充)
(原始报告中 default chunks 已给出,核心趋势:text2vec avgMs ≈ 35.7ms,bge ≈ 114.0ms。)
| 模型 | avgMs(窗口模式四书均值) | 章节模式 avgMs | 变化 (窗口 - 章节) | 变化百分比 | 说明 |
|---|---|---|---|---|---|
| text2vec | (36.5+35.6+34.8+36.0)/4=35.7 | 51.9 | -16.2 | -31.2% | 更细粒度分块显著降低延迟 |
| bge | (116.0+119.0+118.2+102.9)/4=114.0 | 116.2 | -2.2 | -1.9% | 分块细化对 bge 延迟影响较小 |
观点:text2vec 对“减小文本长度”更敏感(延迟下降幅度大),适合“积极窗口化”策略;bge 延迟相对稳定,可在不剧烈切分的场景保持语义完整度。
5. Phase 2:语义检索章节召回原始数据(Top1 / AvgTop5)
5.1 原始查询结果(节选:三国 + 红楼 示例)
| 模型 | 小说 | 查询 | Top1 | AvgTop5 |
|---|---|---|---|---|
| text2vec | 三国 | 诸葛亮 草船借箭 | 0.5714 | 0.5566 |
| text2vec | 三国 | 刘备 三顾茅庐 | 0.6216 | 0.6150 |
| text2vec | 红楼 | 贾宝玉 初见 林黛玉 | 0.5494 | 0.5251 |
| text2vec | 红楼 | 宝钗 黛玉 性格 对比 | 0.5268 | 0.4915 |
| bge | 三国 | 诸葛亮 草船借箭 | 0.6024 | 0.5750 |
| bge | 三国 | 关羽 过五关斩六将 | 0.5641 | 0.5598 |
| bge | 红楼 | 贾宝玉 初见 林黛玉 | 0.5861 | 0.5799 |
| bge | 红楼 | 宝钗 黛玉 性格 对比 | 0.6867 | 0.6499 |
(其余查询见完整报告,此处不重复粘贴。)
5.2 novel 内 Top1 均值对比
| 小说 | text2vec Top1 均值 | bge Top1 均值 | 差值 (t2v - bge) | 相对差异 | 胜出模型 |
|---|---|---|---|---|---|
| 三国演义 | 0.586 | 0.573 | +0.013 | +2.3% | text2vec |
| 水浒传 | 0.557 | 0.544 | +0.013 | +2.4% | text2vec |
| 红楼梦 | 0.543 | 0.577 | -0.034 | -5.9% | bge |
| 西游记 | 0.604 | 0.565 | +0.039 | +6.9% | text2vec |
| 四书宏均值 | 0.5725 | 0.5649 | +0.0076 | +1.3% | text2vec 轻微领先 |
观点:整体 Top1 差异“绝对值”很小(≈0.008)。说明两个模型在这些“显式人物+事件”查询上都能聚焦语义;优势主要体现在某些题材(红楼/人物情感 vs 战役/神话事件)。
5.3 AvgTop5 均值(结果集中度)
| 小说 | text2vec AvgTop5 | bge AvgTop5 | 差值 (t2v - bge) | 结论 |
|---|---|---|---|---|
| 三国演义 | 0.567 | 0.555 | +0.012 | text2vec 结果列表稍集中 |
| 水浒传 | 0.521 | 0.499 | +0.022 | text2vec 稳定性稍好 |
| 红楼梦 | 0.522 | 0.550 | -0.028 | bge 对人物关系更聚焦 |
| 西游记 | 0.553 | 0.525 | +0.028 | text2vec 对神话事件聚焦更强 |
| 四书宏均值 | 0.5408 | 0.5322 | +0.0086 | text2vec 略集中 |
观点:text2vec 在“战役/武侠/神话”类关键词组合中聚焦度更高;bge 在“人物性格/抽象描述”类更胜。这提示可以做“意图类型 → 模型路由”:事件/动作类走 text2vec,关系/性格/抽象类走 bge 或 rerank。
5.4 单条差异典型案例
| 查询 | 小说 | text2vec Top1 | bge Top1 | 差值 | 解释性猜测 |
|---|---|---|---|---|---|
| 宝钗 黛玉 性格 对比 | 红楼梦 | 0.5268 | 0.6867 | -0.1599 | bge 对“对比+抽象属性”组合概念空间表达更充分 |
| 火焰山 芭蕉扇 | 西游记 | 0.7046 | 0.6557 | +0.0489 | text2vec 在典型事件/实体具象词更匹配章节标题正文 |
| 刘备 三顾茅庐 | 三国 | 0.6216 | 0.5800 | +0.0416 | text2vec 可能对该经典桥段的多词共现更敏感 |
| 王熙凤 管理 手腕 | 红楼梦 | 0.5323 | 0.5148 | +0.0175 | 两者差距小,属于噪声区间,需扩大查询集合验证 |
观点:大幅差异主要集中于“抽象属性 + 人物对比”类;说明更高维的 bge 在复杂语义组合上具潜在优势,而 text2vec 在典型事件指称类场景更高效。
5.5 召回“稳定性”与“可分性”
可用 (Top1 - AvgTop5) 衡量“头部尖锐度”,差值越大说明第一命中明显优于后续:
| 小说 | 模型 | Top1-AvgTop5 (均值) | 解释 |
|---|---|---|---|
| 红楼梦 | bge | (0.577−0.550)=0.027 | bge Head 更突出(聚焦性格/情感类概念) |
| 西游记 | text2vec | (0.604−0.553)=0.051 | 事件型关键词 head 强(检索首条明显优) |
观点:对于需要“首条章节高可信”场景(如直接引用章节回答),可倾向选择在该类语料上 head-gap 更大的模型。
6. 关键数据驱动结论(浓缩版)
| 结论类别 | 结论 | 数据支撑 | 落地建议 |
|---|---|---|---|
| 性能 | text2vec avgMs 约为 bge 45%(章节模式 51.9 vs 116.2) | §3.1 | 大批量初始入库 / 高频重算首选 text2vec |
| 尾延迟 | text2vec p95 平均 186.8 vs bge 240.8 | §3.1 | SLA 严格系统更易控延迟抖动 |
| 模型范数 | normStd≈0 双方一致 | §3.2 | 需另建健康探针(向量采样余弦分布) |
| 事件/动作类召回 | 三国/水浒/西游 text2vec Top1 均领先 | §5.2 | “历史战役/武侠情节/神话道具”类优先 text2vec |
| 人物关系/性格类 | 红楼梦 bge 明显领先 (0.577 vs 0.543) | §5.2 / §5.4 | “人物性格对比/抽象关系”场景考虑 bge 精排 |
| 结果集中度 | AvgTop5 text2vec 四书宏均值 0.5408 > 0.5322 | §5.3 | 快速检索直接用 Top5 时 text2vec 稍省 rerank 成本 |
| 极差案例 | “宝钗 黛玉 性格 对比” bge 高 0.16 | §5.4 | 为抽象多实体对比类建立模型路由或二次 bge 复算 |
| Head-Gap | 西游记 text2vec gap=0.051 | §5.5 | 若首条命中权重高,偏事件类语料可用 text2vec |
| 综合取舍 | 延迟/吞吐优先 → text2vec;语义精细+人物抽象 → bge | 全文 | 构建“语义意图 → 模型/流程”规则更优于单一模型 |
7. 代码实现亮点(以评测可信与复用为核心)
| 组件 | 说明 | 价值 |
|---|---|---|
| DoupoNovelSplitter | 多正则 + 超长章节二级窗口 + 噪声过滤 | 提升章节识别鲁棒性,降低 fallback 变量干扰评测 |
| 多编码读取 | UTF-8→GBK→GB2312 评分选择 | 减少乱码误判章节结构的偏差 |
| 章节/窗口双策略 | 同源语料多粒度视角 | 便于分析“分块粒度对性能 & 召回”的交互影响 |
| 统一采样 + p95 | 避免少量极端 chunk 掩盖整体趋势 | 让延迟结论更稳健 |
| 缓存章节向量 | 仅对查询重复 embed | 降低 Phase2 时间,聚焦模型质量而非 I/O |
| 多格式报告 (MD/JSON/CSV) | 数据可读 + 易进入 BI / Notebook | 降低二次统计门槛 |
| 并发可配置 | 系统属性控制线程数 | 允许横向扩展“QPS vs 延迟”曲线分析基础 |
8. 关键代码片段(示例裁剪)
// 并发或单线程采样嵌入
private BenchmarkResult embedSample(EmbeddingModelAdapter adapter, List<String> chunks, int cap) {
List<String> sample = total > cap ? chunks.subList(0, cap) : chunks;
if (EMBED_THREADS <= 1) { /* 顺序 */ } else { /* 线程池并发 */ }
// 统计 totalMs / avgMs / p95Ms / normMean / normStd
}
// 查询召回(缓存章节向量)
float[] qVec = adapter.embed(query);
for (float[] v : cachedVectors) scores.add(cosine(qVec, v));
// 排序取 top1 + avgTop5
9. 实践落地策略(基于数据推导而非空谈)
| 场景 | 推荐流程 | 理由 |
|---|---|---|
| 大批量历史文档入库 | text2vec 全量构建向量库 | 2.2x 速度优势降低初次构建成本 |
| 在线高并发 FAQ / 历史事件问答 | text2vec 直接 TopK →(可选轻量 rerank) | 事件类召回优势 + 更低延迟 |
| 人物关系 / 抽象讨论问答 | text2vec 初筛 TopK → bge 精排或 bge 直接 | 红楼梦差异显著,bge 擅长抽象组合 |
| 多意图融合问答 | 意图分类(事件/人物性格/物品)→ 模型路由 | 充分利用两模型互补性 |
| 首条精度敏感(引用章节原文) | 选 head-gap 更大模型(西游场景 text2vec) | Top1 更易与人工答案对齐 |
| 资源受限但需质量提升 | text2vec 全局 + 针对“抽象/人物”触发 bge 二次 | 控制算力同时击中弱项 |
采用“分意图路由”往往比“单模型全场景”更具性价比:本次数据已经给出各语义细分类型的倾向性证据。
10. 快速复用步骤
仓库与文件位置
| 类型 | 路径(相对于仓库根) |
|---|---|
| Git 仓库 | https://gitee.com/zhangjq123/langchain4j-spring-agent |
| 模块根 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2 |
| 小说文件-三国演义 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/小说/三国演义.txt |
| 小说文件-水浒传 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/小说/水浒传.txt |
| 小说文件-红楼梦 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/小说/红楼梦.txt |
| 小说文件-西游记 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/小说/西游记.txt |
| 测试类 | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/src/test/java/com/soft/nda/chat/embedding/EmbeddingModelComparisonTest.java |
| 报告输出示例 (Markdown) | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.md |
| 报告输出示例 (JSON) | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.json |
| 报告输出示例 (CSV) | langchain4j-spring-ai/langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.csv |
小说 txt 位于模块内
小说/目录;测试类在src/test/.../embedding/;评测生成的多格式报告在模块target/目录下。运行测试前请确保上述四个 txt 文件存在并保持编码可被自动检测。
# 运行评测(例:线程数 4)
mvn -pl langchain4j-spring-ai-chat-v2 -am test -Dtest=EmbeddingModelComparisonTest -Dembedding.benchmark.threads=4
# 查看多格式输出
cat langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.md
cat langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.json
cat langchain4j-spring-ai-chat-v2/target/embedding-comparison-report.csv
11. 总结(数据支撑的核心答案)
- 性能:text2vec 明显更快(章节 avgMs 约为 bge 45%),适合“底座批量 + 高频查询”。
- 语义召回整体差异很小(Top1 平均差仅 0.0076),需按语义类型细分。
- 语义类型分化:人物性格/抽象对比 → bge;事件/场景/物件 → text2vec。
- 无需二选一:用“意图分类 / 条件 rerank / 双模型协同”组合收益更高。
- 范数不可用作唯一健康指标:需补充随机向量分布监控。
最后:如果你正在做中文 RAG / 知识库问答,这套方法可以直接套在你的行业语料(法务、医药、金融规章)做客观选型。欢迎留言交流你在真实业务里观察到的“语义类型差异”。
如果这篇文章对你有价值,欢迎点赞 / 收藏 / 评论交流。

1528

被折叠的 条评论
为什么被折叠?



