
狐狸研究AI日记
Lv.1靠咖啡和好奇心维持运行的技术生物。关注AI应用开发,主要分享企业场景落地、模型部署和推理优化和日常踩坑;不追求堆砌概念,只记录验证过的经验。记录不一定完美,但力求真实、清楚、可验证。
发表的评论
技术文档和闲聊文本肯定不能一套切法,前者结构清晰可以按标题层级切,后者更适合按语义段落来。我自己的经验是别死磕固定字符数,先用语义分割再对超长块做二次切分,效果比纯按256/512切稳很多。另外可以搞个小的评测集,拿问题去跑召回率,比凭感觉调靠谱。你们现在有做检索效果的自动化评估吗?
我也有过这个阶段,一开始觉得prompt写得越“专业”模型就越听话,后来发现完全不是那么回事。你提到的“专家模式思考”和一堆角色设定,其实很容易让模型把注意力放到表演一个专家上,而不是老老实实解决你的具体问题。特别是像Aider这种工具,它本身已经在系统层面做了不少约束,你再叠一堆格式要求,反而把真正重要的需求信号给稀释了。我现在写这类脚本基本就三步:一句话说清楚要干什么,列出两三个关键约束,然后
bge-small-zh确实有点吃力,尤其是你这种内部知识库场景,离职和入职这种词在字面上共享了“职”这个语义维度,小模型很容易把它们映射到相近的向量空间里。我之前也踩过类似的坑,后来换成bge-m3之后召回质量提升挺明显的,它对中文长文本和多粒度语义的区分能力比small强不少。不过换模型之前建议你先排查一下chunking策略,如果chunk切得太碎或者没有overlap,再好的embeddi
这个其实挺常见的,Cursor默认会倾向于生成“教学风格”的代码,尤其你让它写小脚本的时候,它默认假设你可能不太熟,所以注释和错误处理都给你堆上。光在prompt里说“不要注释”确实不太管用,因为系统级的行为优先级更高。你可以试试在项目根目录建一个 .cursorrules 文件,里面写清楚“生成代码时不要添加解释性注释,除非我明确要求”以及“不要自动添加try-except,除非涉及IO或网络操
chunk_size和embedding其实得一起看,bge-large-zh对512长度还挺友好的,但文档如果结构清晰,可以试试按段落或标题切,再留个10%-20%重叠。top_k我一般先设10再配rerank,单靠向量召回确实容易漏。rerank提升挺明显的,尤其bge-reranker这类,能把相关但向量分数不高的捞回来,建议加上试试。
两张3090跑7B还开TP=2,这个组合本身就有点尴尬——TP的通信开销在PCIe上很肉疼,而7B单卡24G其实塞得下AWQ 4bit,不如直接单卡跑,省掉卡间同步那部分浪费。GPU利用率40%也说明瓶颈大概率不在算力上,而是在调度或者请求侧,比如你的batch里是不是大部分时间只有一两个活跃请求,continuous batching根本没吃饱。另外AWQ在vLLM里对7B这个尺寸的加速比其实没
我踩过差不多的坑,后来发现Agent乱跳工具往往不是框架问题,而是工具描述和边界没写清楚。比如“查订单”和“查物流”两个tool语义重叠,模型当然会反复横跳。建议先把每个tool的输入输出、什么场景用、什么场景不用写死,再手动编排跑通主流程。框架能帮你管状态和重试,但决策逻辑还是得自己先理明白,不然换啥框架都白搭。
指数退避确实比无脑重试靠谱,但关键得先区分是网络抖动还是工具真挂了,前者重试有用,后者趁早降级或换备用工具。
你这个loss震荡的情况我太熟悉了,500条数据用3e-4的lr确实有点猛,尤其LoRA本来学习率就得比全量微调大一点,但大到这个程度就容易在最优解附近反复横跳。另外你的数据格式确实太随意了,instruction和output之间没有明确的边界标记,模型很难区分哪儿是输入哪儿是输出,建议至少加上### Instruction:和### Response:这种分隔符,或者直接套alpaca模板也行
我之前也踩过这个坑,单靠主Prompt让模型自己拆步骤确实容易丢上下文。后来改成把每一步的输出显式塞进下一步的输入里,比如“已知天气=雨天,请推荐穿搭”,就稳多了。ReAct不是必须的,但它的思路——把中间结果写进prompt——挺关键。你可以试试让Agent每步都输出个简短的状态摘要,下一步直接引用那个摘要。
你遇到的乱码其实是Unicode转义,`\u00e4`这种是UTF-8字节被当成latin-1解码了,不是模型的问题,检查下Ollama的返回编码和你的解析层。JSON里夹Markdown很常见,7B模型指令遵循本来就弱,系统提示里最好给个few-shot示例,光说“严格JSON”它真不一定听。清理的话直接在代码里正则抽`{...}`再json.loads就行,别指望模型每次都乖。
4-5秒确实偏慢了,4080跑7B不该这样。你CPU利用率不高的话,重点看看是不是每次请求都在重新prefill那800字工具描述——vLLM默认没开prefix caching的话,多轮对话每轮都要重算system prompt,这开销很吓人。建议开enable_prefix_caching试试,另外确认下有没有用AWQ或GPTQ量化,fp16的话显存占用不止10G。温度0.7对延迟影响不大,但
我也踩过这坑,全局系统提示词定风格+每步只写增量指令会稳很多,不然光对齐格式就累死。
YOLOv8-seg的dynamic shape确实挺容易踩坑,我之前也折腾过一阵。建议先检查ONNX导出时的min/opt/max三个shape有没有对齐,TensorRT建engine时用的profile必须跟实际推理输入落在同一个区间里,不然就会报你那个不兼容。另外ultralytics默认导出的opset有时候偏旧,可以试试手动指定opset=17再转,还有TensorRT 8.6对seg
我最近也在踩这个坑,后来是把历史记忆拆成两层:近期几轮保留原文,更早的用LLM压缩成结构化摘要,只留实体和结论,效果比单纯滑窗好不少。向量存历史确实容易时序混乱,可以给每条记忆打时间戳和对话轮次,检索时加权排序。记忆单独做子Agent管理听起来有点重,除非业务特别复杂,不然先试试摘要加关键信息抽取这条路。
先别急着换模型,合同这种长文档固定512分块很容易把关键条款切碎,试试按条款或段落语义分块。索引影响不大,62%的召回率八成是分块背锅。
做Agent的话PyTorch生态现在完全够用,部署那点坑咬咬牙就过了,别为了TF Serving回头折腾静态图。
中英文混杂的场景确实比较头疼,bge和text2vec各有侧重。我们项目文档量跟你差不多,后来试了m3e-base,中文召回比bge稳一些,维度也降到768,FAISS跑起来快不少。几千条数据其实不用太纠结模型,chunk切分策略影响更大,中文建议按句号加换行切,重叠别超过20%,不然长句容易被截断。你可以拿几十条真实query做个对比测试,比看评测榜靠谱。
你这情况我熟,3090跑7B agent确实紧巴巴。我试过把历史对话用摘要压缩成固定长度,只保留最近两轮原始消息,显存能省下不少。另外可以试试用--enable-chunked-prefill把长prompt分成块处理,vLLM里这个开关对显存尖峰挺有效。还有个偏方是把工具调用的system prompt精简到极致,能砍一点是一点,实测能省个几百M。
说实话你这个情况我太熟了,之前做个法律问答也栽在同样坑里。我觉得问题不一定全在向量化,你那个query本身“合同违约金怎么算”就是典型的高频抽象表达,embedding容易把它跟“合同条款概述”这类泛文本拉近,而“按日万分之五”这种具体数字在向量空间里反而不吃香。我后来是直接上了BM25+向量的混合检索,把关键词命中单独加权,效果立竿见影,排名直接从第8跳到第2。rerank我也试过,但感觉得排在