转码学习day12

toc

今天没正儿八经学习,昨晚熬夜看了森载大战,一点都不好看(悲)。早上睡了五个小时起来了,要倒一下生物钟,因为明天要早起赶高铁回家。

lc:146LRU缓存,python常用的api是move_to_end ,last = False 是LRU, True则是MRU

默写MHA一次。

茶余饭后冲浪的时候粗浅了解了一下RAG,发现很多实现场景其实用的是纯文本交互,因为大模型本身就擅长从纯文本内容里推理归纳总结。因为是纯文本,RAG检索用的embedding模型可以和推理模型完全不同,它把文本 → 向量,用于在知识库里检索,Embedding 的目标是“语义相似度”。

🌍 世界 A:向量检索世界#

  • 语言:向量
  • 模型:bge / e5 / text-embedding
  • tokenizer:只服务 embedding 本身
  • 目标:找相似内容

🌍 世界 B:生成世界#

  • 语言:token
  • 模型:DeepSeek / Qwen / GPT
  • tokenizer:生成质量相关
  • 目标:组织语言

这两个世界只通过“文本字符串”交汇一次。 在工程上,Embedding 模型的选择只需要满足:

  1. 与你的语料语言匹配 - 中文 → bge-large-zh / m3
  2. Query 与 Document 使用同一个 embedding
  3. 向量维度固定 为“检索优化训练”(不是通用 sentence embedding) embedding 模型是:
  • 只做 encoding 的 Transformer
  • 前向推理一次就结束 它是Inference-only encoder model哦,并不是GPT架构,Encoder 比 decoder 更适合 embedding,是因为它被设计成“为整段输入建立全局、对称、位置无关的表示”,而 decoder 的设计目标是“为下一个 token 建立条件分布”。embedding 需要“位置不敏感”,decoder 正好相反。

它的训练目标决定了“头”在学什么#

Encoder embedding 模型#

  • 对比学习
  • ranking loss
  • sentence-level supervision

训练目标直接约束:

“整句向量是否表达语义相似性”

工业界的共识是:

LLM embedding = 可用,但不优雅、不稳、不便宜

cross-encoder 适合 rerank,而 bi-encoder 适合 recall#

结论#

recall 要“快且不漏”,rerank 要“准且可贵”。

Bi-encoder(适合 recall)query / doc 完全独立编码 👉 粗语义过滤器

Cross-encoder(适合 rerank)query 和 doc 在 attention 中全交互 👉 精语义判官

embedding 空间会出现各向异性(anisotropy)#

现象#

  • embedding 大量集中在一个窄锥体
  • 向量彼此夹角很小
  • cosine similarity 区分度下降

原因#

Transformer 的残差与 LayerNorm#

  • 多层残差叠加 → 向量均值漂移
  • LayerNorm 让不同输入“形态相似”

训练目标不惩罚“塌缩”#

  • 对比学习只关心:

    • 正样本更近

    • 负样本更远

  • 不关心全空间是否均匀

高频语义主导#

  • 常见抽象语义(“描述、问题、事情”)

  • 主成分被强力共享

在embedding model里pooling 比想象的重要#

embedding 模型的监督是:

  • sentence-level

  • loss 直接作用在 pooling 后的向量 👉 pooling 是 loss 的直接受体

instruction-tuned encoder 反而可能变差#

把 encoder 从:

“压缩语义”

推向:

“对指令作出有用反应”

从而导致了“ 输出对 prompt 敏感、风格 / 语气 / 任务指向性、语义被条件化

看完了之后想了一下,发现了RAG的核心难点在于:词向量不能太密集,毕竟我们是在比较相似度,如果太密集了就没有区分度了,操作上是把prompt输入映射成一个点,然后把doc和它在同一空间最相似的内容拉取出来,这里都还好,但我们得到的可能是recall得到的多个相似内容,它们还需要排列重要度的rerank,要恢复原有doc中的细节结构,cross-encoder快速判断相似文本和prompt的联系紧密程度,它一般不用于recall。不是因为它不准,而是因为它太“贵”。

  • 每个 (q, d) 都要跑一次 encoder
  • O(N) 前向
  • 无法预计算
  • 无法 ANN 所以它被放在 top-k 小集合上。