跳到正文

RAG向量化流程:预处理到归一化

文本预处理、Embedding 选择到向量归一化全解析

原题:请描述在RAG系统中对文档或查询进行向量化处理的流程,包括文本预处理、嵌入模型选择、向量生成及归一化等关键步骤。

文档处理 · 安克科技真题

30 秒回答

  1. 文本预处理策略(分块、清洗、元数据保留)
  2. Embedding模型选型依据(中英双语、上下文长度、领域适配)
  3. 向量生成与批量优化
  4. 归一化的作用(余弦相似度计算)

回答与解析

答案要点

  • 文本预处理策略(分块、清洗、元数据保留)
  • Embedding模型选型依据(中英双语、上下文长度、领域适配)
  • 向量生成与批量优化
  • 归一化的作用(余弦相似度计算)
  • 实际工程中的注意事项(并发、缓存、版本管理)

文本预处理

核心目标:保留语义完整性,控制块大小

  • 文档解析:PDF用PyMuPDF/MinerU,HTML去标签,表格保留结构
  • 分块策略:按语义段落切分,并比较多组 chunk size 与 overlap 候选,用同一评测集验证边界召回和成本
  • 清洗降噪:去页眉页脚、统一编码、过滤低信息密度内容
  • 元数据绑定:保留标题层级、来源URL、时间戳,用于过滤和重排序

嵌入模型选择

选型三要素

维度 考量
语言 中英混合选bge-m3、gte-large;纯英文选text-embedding-3-large
上下文 长文档需≥8K上下文,否则先做摘要
领域 垂直领域用微调模型(如医学用PubMedBERT)

调用方式:优先用私有化部署(Xinference/TEI),API兜底

向量生成与优化

  • 批量编码:batch_size设32-64,GPU利用率最大化
  • 动态批处理:同请求内文档长度对齐,减少padding浪费
  • 缓存机制:文档哈希去重,避免重复编码

归一化

import torch.nn.functional as F
embeddings = F.normalize(embeddings, p=2, dim=1)  # L2归一化

必要性:将向量映射到单位球面,使余弦相似度等价于点积,加速Milvus/PGVector的检索计算

工程注意

  • 版本管理:模型更新时全量重刷向量,或双版本并行灰度
  • 维度对齐:不同模型输出维度不同(768/1024/3072),入库前校验
  • 监控埋点:记录编码耗时、缓存命中率、向量分布漂移

口语版讲法(约4分钟)

  • 一句话定位:RAG落地的核心工程问题
  • 文本预处理:分块与元数据保留
  • 嵌入模型选择:业务场景决定模型
  • 向量生成与归一化:批量与缓存优化
  • 风险与取舍:版本管理、维度对齐

这道题其实问的是RAG落地的核心工程问题,怎么把非结构化的文档和用户查询,转成计算机能高效检索的向量。说白了,这中间每一步都有取舍,不是一个模型一套流程走到底的。

先说文本预处理。很多人觉得就是切切文档,但这里有个挺关键的边界:固定长度切分和语义切分的区别。固定切分简单,但照搬一个固定长度很容易把一句话或者一个逻辑断成两半,检索的时候召回的内容不完整。语义切分就好很多,比如按段落、按标题层级来分,甚至可以用LLM辅助判断自然断点。但语义切分也有代价,就是计算开销大,而且有些文档结构不清晰,反而切不好。所以真正落地的时候,我倾向混合策略:对结构清晰的文档用语义切分,对纯文本或结构混乱的,也要把多组固定长度与无重叠、短重叠、较长重叠作为候选,用同一评测集验证断句、召回、答案质量和成本。另外元数据一定要保留,比如来源、标题层级、时间戳,这能让后面的过滤和重排事半功倍。举个例子,在客服退款场景里,用户问的是'退款流程',如果文档切分时把标题'退款政策'和正文'退款流程'分到不同块,检索时就可能只召回标题块,内容不全。所以我会把标题、层级这些元数据绑到每个块上,检索时优先返回。

接下来说嵌入模型选择。这块很多人有个误区,觉得模型越新越大越好。其实选模型要看三个前提:语言、上下文长度、领域。中英混合的场景,我会优先选bge-m3或者gte-large,它们在双语上都比较均衡;纯英文场景,OpenAI的text-embedding-3-large效果很好,但私有化部署成本高。上下文长度是关键,如果文档块超过模型支持的长度,直接截断会丢失信息,所以要么选支持8K甚至32K的模型,要么先做摘要。领域适配更是个坑,垂直领域比如医学、法律,通用模型的效果可能很差,我见过一个医疗合同检索项目,用通用模型召回率不到60%,换成PubMedBERT微调后直接拉到85%以上。所以选型时我会先拿业务数据跑个benchmark,不盲目跟风。

再一个,向量生成和归一化。批量编码是必须的,batch size设到32到64,能充分利用GPU。但这里有个工程细节:同批次里的文档长度差异太大,短的会被大量padding浪费计算,所以我会做动态批处理,按长度排序分组,让相近长度的一起编码。归一化也很关键,L2归一化之后,余弦相似度就等于点积,这样在Milvus或者PGVector里检索时,计算更快,而且索引结构也更稳定。如果不做归一化,不同向量的模长差异会影响相似度排序,导致长文档天然容易被召回,这在很多场景下是灾难。

最后说落地风险和工程注意。版本管理是个大坑,模型更新后,新老向量分布不同,直接混用会导致检索质量崩盘。我一般会做全量重刷,或者用双版本并行,灰度切换,等新版本稳定了再下掉旧的。还有一个常见失败场景是维度不对齐,不同模型输出维度不一样,768、1024、3072都有,入库前必须校验,否则查询时会直接报错。上线后我会特别关注监控埋点,比如编码耗时、缓存命中率、向量分布漂移,如果分布漂移太快,说明业务数据变了,可能需要重新切分或微调模型。

说到监控,我发现很多团队只关注召回率,但其实检索延迟和存储成本的平衡才是线上真正的瓶颈。比如HNSW索引参数调不好,召回率再高,延迟超标也上不了线。这块其实可以深挖一下。

所以整体上,我会把向量化流程看成一个根据业务场景不断迭代的工程系统,而不是一套固定的脚本。预处理、模型选择、归一化、版本管理,每一步都要和业务数据对齐,上线后持续观测,才不至于变成'离线跑分高、线上效果差'的尴尬局面。

关键一句:检索延迟和存储成本的平衡是线上真正的瓶颈,HNSW参数调不好召回率再高也上不了线。

面试官还可能这样问

  1. 问法 1 · 场景切入

    假设咱们做一个企业知识库问答,用户上传了一堆混合了中英文的PDF和网页。你怎么把这些文档切成合适的片段,然后转成向量存到库里?从文本清洗到最终向量入库,你具体怎么走?

  2. 问法 2 · 层层追问

    做RAG检索时,文档和查询怎么变成向量的?……那你文本预处理一般怎么做?……选embedding模型要考虑哪些因素?……向量生成后为什么还要归一化?

  3. 问法 3 · 直球架构

    请描述RAG系统中文档或查询的向量化全流程,重点讲文本预处理策略、embedding模型选型依据、向量生成与批量优化,以及归一化的作用。工程上有什么注意事项?

同模块相关题目