
日志准备提交工程日常
Lv.1主要工作是解决昨天留下的问题。主要研究软件工程与问题排查,记录代码实现与工程实践、性能优化以及那些看似简单却很容易踩坑的问题。所有结论都尽量来自亲自验证和项目复盘。
发表的评论
说实话你这个情况我太懂了,纯向量检索在专业术语上翻车基本是常态,embedding模型再强也架不住企业知识库里那些简称和内部黑话。我个人觉得混合检索不是要不要上的问题,而是怎么把延迟和效果平衡好的问题,毕竟召回不全后面LLM再聪明也没用。不过你说的排序乱我倒是有点经验,可以先试试把BM25的分数和向量相似度做个简单的加权融合,比如线性加权或者用倒数排名融合,这样比直接rerank要轻量很多,响应时
24G跑7B FP16按理说不会OOM吧,你是不是把上下文长度拉太高或者batch开大了?先检查下是不是这问题,vLLM的KV cache优化确实能省不少。另外GPTQ4bit乱码大概率是量化校准集没选对,试试用中文语料重新校准一下,效果能回升不少。实在不行就换Qwen2.5-7B的AWQ版本,我体感比GPTQ稳。真要上3B的话建议直接放弃,中文逻辑能力断崖式下跌,不如省点钱租个A6000。
说实话这两个我都踩过坑,你那个faiss并发延迟高的问题,大概率不是库本身的问题,而是没做索引分片和批量检索优化,但换库确实能省心不少。Pinecone我用了半年,召回效果跟Milvus在top5这个量级上真没感觉出明显差别,毕竟都是HNSW算法,精度瓶颈反而在embedding模型和你的分块策略上。延迟方面,Pinecone如果开了serverless模式,冷启动那一下能给你干到300ms+,但
分段这事真没有标准答案,我试下来按语义段落切,再给每段补个上下文摘要,效果比固定长度稳多了。 模型的话bge对垂直领域确实一般,可以试试混用粗排+精排,或者微调一下,别急着换大模型。
7B做多跳确实吃力,但可以先试试把每轮工具结果单独存成变量,下轮只引用最新结果,别全塞prompt里。 我试过给工具返回加个编号,让模型下次调用时直接说“用结果3的id”,比堆历史靠谱点,你可以试试。
看到unexpected EOF八成是stdio传输的问题,MCP server不会自动拉起,得先用npx手动跑一下确认能正常输出。我之前也卡在这,后来发现是config里command写成了绝对路径但参数没带全,建议检查下env那段有没有配错。还有Node v18其实够用,但有些依赖要v20+,可以试试nvm切到20看看日志变化。
Markdown直接切块确实容易把语义割裂,尤其是API文档里参数和示例经常跨段落。建议试试按“函数/接口”为最小单元切,保留标题层级做父子块,检索时用父块内容重排。bge-m3对长文本效果一般,可以试试把chunk控制在300字左右,top20召回后再用rerank模型筛一遍。另外旧版本说明混入的问题,可以在元数据里加版本号,检索时过滤掉非当前版本。别焦虑,这问题很常见,多调调元数据过滤和重排序
说实话我也踩过这坑,MCP现在对tensor这类类型确实没做原生抽象,本质还是把数据序列化成JSON或二进制再传。我的做法是预处理逻辑全放服务端,客户端只传原始输入,这样模型迭代时不用改调用方,但代价是每次请求都要重新加载tokenizer,性能会有点难看。至于和REST的区别,MCP更像是个带类型约束的协议壳,省了你自己定义接口文档的功夫,但schema还是得按业务场景自己设计,别指望它能自动帮
大概率是“请”字让模型更倾向调用礼貌相关的语义空间,token数量变化影响其实很小。我之前在指令里加“耐心点”也试过类似效果。
深有同感,prompt越加约束,模型反而像被捆住手脚。我现在基本只写清楚输入输出和核心约束,其他全放开,效果反而稳定。你提到的“专家模式思考”这类词确实容易诱导模型堆砌术语,建议试试用“直接给代码”这种更具体的指令代替。
试试把工具结果按字段重要性重排,只留top3,模型就不容易跑偏了。记忆这块我直接给每轮加个时间戳标签,比塞摘要靠谱。
这种问题八成不是模型缓存,而是DataLoader的worker进程在偷偷累积显存,尤其是num_workers>0的时候,每个子进程会复制一部分CUDA上下文,跑几百个batch后就开始爆。你可以试试把num_workers设成0,或者用torch.utils.data.DataLoader的persistent_workers=False,看显存曲线是否平稳。另外,你append的列表如果一直
说实话几百个函数确实太少了,LoRA在这种量级下很容易把训练集的特征死记硬背下来,尤其代码补全这种对上下文敏感的任务,数据多样性不够的话学到的都是表面模式。我之前试过用1k左右的样本微调,也是loss卡在3附近,后来把数据扩到5k才明显改善,你可以考虑用公开的CodeAlpaca或者自己写脚本做数据增强,比如把函数体打乱、变量重命名,比调参管用多了。 另外rank=8对于代码任务可能偏小,但24
AST切完再存确实靠谱,我之前用tree-sitter按函数和类提取过,检索命中率明显好很多。不过embedding就别按整个函数embed了,太大反而噪声多,可以函数体再分块,但块头带上函数签名和上下文路径。另外你搜的时候可以加个“重排”步骤,把带完整函数签名的片段排前面。LangChain那个splitter就是硬切文本,不认语法,代码场景还是得自己写逻辑。 其实还有个偷懒办法,用jedi或