
持续学习的前端手记
Lv.1一名专注于前端工程的前端工程师。日常记录框架实践、浏览器原理和项目中的问题解决过程;希望内容既讲清为什么,也说明怎么做,也会分享日常思考、问题排查和阶段性总结。
发表的评论
几百万条embedding还要增量更新和过滤,faiss确实不太适合了。我去年从faiss迁到Qdrant,Docker一条命令起服务,增量插入和payload过滤都很顺手,内存占用也比想象中低。Milvus功能更全但组件多,部署维护成本高一些,看你团队有没有精力折腾。如果并发不高又不想引入新组件,pgvector其实也能扛住几百万量级,就是过滤加向量混合查询时性能会明显掉,得自己权衡。
几百万这个量级pgvector其实完全扛得住,你们已经在用PG的话运维成本最低,先跑起来再说。不过实时写入频繁的话得注意vacuum和索引重建的节奏,不然查询会突然变慢。HNSW那个m和ef_construction别太纠结,先用m=16、ef_construction=200跑baseline,再根据召回率微调ef_search就行。真要上千万级再考虑迁Milvus也不迟,Qdrant我用下来过
你这个情况我太熟了,之前做合同问答也踩过一模一样的坑。报销流程和差旅标准被混召回,大概率不是embedding的问题,而是chunk里本身就混着这两类内容,向量再强也分不开。PDF和Word里表格、标题、正文混排,你直接按字数切,等于把语义单元打碎了,bge再大也救不回来。建议先做结构识别,按标题层级和表格边界切,表格最好单独序列化成文本再入索引。另外chunk_size调到200其实有点小了,容
百万级ES的KNN确实容易跪,内存和分片调不好直接拖垮集群,我们后来还是咬牙上了Qdrant。
7B这个量级对prompt确实敏感,你这个现象挺正常的,不是姿势问题。我拿Qwen2.5-7B和14B都跑过类似的任务,同一个提示词换两次温度采样结果都能差出一截,更别说改措辞了。关键问题在于小模型对“完整代码”这个指令的理解不够稳,你光说“确保能直接运行”,它可能理解为“给个能跑的核心逻辑就行”,中间那些边界处理它就自动省略了。我一般会把它拆成固定几段:先明确输入输出,再要求“逐行注释”,最后补
我之前也踩过这个坑,后来发现关键是separators的顺序,把中文标点放前面会好很多,比如先按句号问号切,再按分号逗号兜底。另外bge-large-zh对512其实挺友好的,我一般chunk_size设400左右,overlap给80,比硬上256强。你还可以试试按标题层级先粗切再细切,法规类文本这样效果不错。工具的话langchain的RecursiveCharacterTextSplitte
动态输入确实会更适合torch.compile,它本身就是为动态shape设计的,JIT反而容易在变长输入上反复触发重编译。你那个自定义注意力掩码大概率会被图断裂,跑一下TORCH_LOGS=graph_breaks看看断在哪。我实测compile在Agent这种变长场景下首token会慢点,但缓存生效后整体还是香的,记得开mode="reduce-overhead"试试。
我目前的做法是短期记忆直接用滑动窗口加摘要压缩,每几轮就把关键状态抽出来重写进system prompt,比全塞进去稳很多。长期偏好那块才走向量库,按需检索top几段注入,不然光靠相似度召回容易把无关的旧偏好也带进来。开源的话可以看看mem0或者letta,思路基本就是你说的分层,但别指望开箱即用,检索阈值和摘要时机都得自己调。
HNSW索引没生效八成是查询时没带过滤条件或参数没对齐,检查下MCP传过去的search_params是不是默认值。
我们之前也踩过类似的坑,bge-large-zh对“违约金”这种偏法律实务的词确实不太敏感,它更擅长通用语义匹配。你分段512带overlap其实还行,但可以试试把合同里违约金条款单独切出来,或者在embedding前给每段加个小标题摘要。另外bge-reranker真的值得上,粗排召回top50再精排,效果提升很明显,比死磕向量检索强。
chunk别光调大小,加个重叠试试,苹果手机和苹果种植多半是没做领域过滤。
我之前也踩过这个坑,八成是Claude Desktop启动server时用的环境变量跟你终端里不一样,Ollama的host或者代理没传进去。你可以在server脚本开头把环境变量打印到日志里,对比一下就知道差在哪了。另外stdio模式下别往stdout写任何调试信息,会污染协议导致超时,日志一律写stderr。
固定长度切分确实容易把语义割裂,尤其是条款类文本,我建议你先按标题或段落做结构切分,再用500字符兜底处理超长段落。另外可以试试给chunk加metadata,比如章节编号,这样检索时能按来源过滤。召回不准不全是切分问题,embedding模型对长文本的语义捕捉也有限,可以试下bge或gte这类中文优化模型。你调top_k的时候有没有顺便看下相似度分数?如果相关片段分数也不高,可能得考虑换rera
试试把权重调到0.3/0.7再跑几组,BM25那路加个长度惩罚,长文档截断再进重排。
说到这个我太有共鸣了,之前我拿GPT做接口文档梳理的时候也这样,明明觉得自己写清楚了,它还是能给你整出点意外惊喜。后来我琢磨出一个笨办法,就是给提示词里加“约束条件”,比如直接告诉它“如果信息不足就明确说不知道,别自己脑补”,效果比反复堆砌指令要稳得多。结构化这东西,我觉得关键不是把每条规则写得多细,而是把任务拆成几个独立的子步骤,让模型一步一步跟着走,像“先提取变更点,再按模块归类,最后标出影响
说实话我觉得问题可能不在embedding模型上,而在你“只靠向量相似度”这个思路本身。Prompt模板之间的差别往往是很细微的“意图边界”,比如商务邮件和产品文案,表面语义重叠度很高,但任务类型完全不同,纯靠余弦相似度很难拉开距离。我建议你试试把模板的类型、场景、输出格式这些维度做成结构化标签,召回的时候先用规则或者一个小模型做粗筛,再在候选集里跑向量相似度,这样比单纯调chunk靠谱得多。另外
A10的显存带宽就那样,你这速度算正常,网上那些40+的大概率是A100或者H20。 试试把max_model_len调低点,再把并发降到4,首token延迟能明显改善。
试试8bit量化或者GGUF的Q5_K_M,比4bit强不少,显存占用也就多3-4G,4090完全扛得住。
说实话你这个问题我太有同感了,我自己拿GPT写数据处理脚本也是这个德行,经常前80%逻辑顺得飞起,最后卡在文件路径或者编码这种破事上。我觉得核心问题在于,单次Prompt其实是在让模型“猜”一个完整程序,但代码的坑往往藏在那些你没提的隐含假设里,比如某个Excel sheet可能为空、列名有空格之类的。你可以试试把任务拆成两轮,第一轮只让它给整体架构和伪代码,你确认逻辑没问题了,再第二轮让它填充具
同款显卡路过,8K上下文KV cache就得吃掉4G多,12G跑8B真不算宽裕,换GPTQ也差不多。