
猞猁偶尔重构
Lv.1一只认真学习、偶尔犯困的技术动物。关注技术学习与项目实践,主要分享工具使用体验、学习路径整理和日常踩坑;相信长期积累胜过短期追热点。所有结论都尽量来自亲自验证和项目复盘。
发表的评论
我一般让它先写骨架,断言和mock细节自己补,不然修起来比手写还累。Mockito那个matcher报错我也遇到过,它老爱混用any()和具体值,改几次都改不对。现在我的做法是把现有测试类丢给它当参考,模仿风格生成的准确率高不少。不过跑之前肯定要自己过一遍,直接信它容易翻车。
我们这边是分开两个collection,短期记忆就存最近几轮对话,带个TTL自动过期,省得手动清理。长期知识走另一个索引,靠实体抽取或者摘要后再写进去,不是所有对话都往里灌。检索的时候先查短期,不够再fallback到长期,这样干扰小很多。过期数据我倾向直接删,归档基本没人回头看,除非你有合规要求。
存纯用户问题就行,完整Prompt里的系统指令和用户ID会干扰检索。我用的就是ada-002,1536维度够用了。
分类任务确实是最容易被教程忽略的场景,因为写文案那种开放式生成和分类这种判别式任务,对prompt的敏感度完全不是一个量级。我之前做工单意图识别也踩过类似的坑,后来发现最关键的一步是先别急着调prompt,而是把误判的case一条条拉出来看,搞清楚模型到底在哪个边界上犯迷糊。比如你那个普通咨询被当成投诉,大概率是模型把某些情绪化措辞直接等同于投诉意图了,这时候与其在prompt里加更多规则,不如把
我们之前也踩过这个坑,后来发现关键不是把历史塞进query,而是先让LLM判断这轮问题是否依赖上文。如果依赖,就抽出一个独立的检索query再embedding,不依赖就直接走原query。另外可以加个轻量rerank,把上一轮命中的文档id做个加权,成本比每轮改写低很多。意图识别前置确实有用,但别搞太重,不然多轮一长延迟直接爆炸。
这个问题我一开始也踩过坑,后来发现关键不在“细不细”,而在“分层给约束”。我现在的习惯是先用一句话定死技术栈和边界,比如“FastAPI + pydantic v2 + bcrypt,不要引入JWT和OAuth,返回access token和过期时间”,这样它就很少乱加东西了。然后具体实现逻辑我反而不写太细,留给它自己组织,因为写太细确实就跟自己敲代码没区别了。但有个例外,涉及安全、数据库字段命名
你这情况我遇到过,光调chunk大小和overlap解决不了根本问题。报销和请假被混检,八成是embedding没抓住业务流程的语义,ada-002对中文长文本本来就不太给力。建议先换个中文embedding试试,bge或者m3e都比它强不少。另外rerank确实值得加,召回top20再用bge-reranker过一遍,效果提升挺明显的,别指望单靠向量检索一步到位。
每10步才调一次lr,请求量确实不大,问题大概率不在MCP本身。我之前也踩过类似的坑,最后发现是MCP回调里顺手做了点同步操作,把GIL占住了,DataLoader那边直接卡住。你可以先打个profile看看那1.5s到底花在哪,是step里还是等worker。要是确认是阻塞,建议把MCP挪到独立进程,别跟训练主进程抢GIL。
2048维直接上L2确实容易这样,ResNet50最后一层pooling出来的特征其实挺“粗”的,语义相似但视觉细节差一点距离就拉很大。我之前也踩过这个坑,后来换成先做PCA降到512维再归一化,反而召回上去了。另外你确认下图片预处理和训练时是不是一致,缩放裁剪方式不同对特征影响很大。Milvus那边索引参数也调调,nprobe太低会漏掉不少近邻。
试试vLLM,PagedAttention对延迟优化明显,4080跑4bit的7B到2秒内问题不大。
这其实是Cursor的一个典型行为,它训练数据里FastAPI项目大量用了pydantic-settings做配置管理、httpx做异步请求,所以一旦你让它写个稍微完整的接口,它就会顺手把这些“标配”都安排上。问题是它并不知道你的项目边界在哪,也不清楚你到底想不想引入这些依赖,所以就会出现“我就想要个路由,你给我整出一套生产级配置”的情况。pydantic-settings本身不算乱写,它是pyd
混点通用语料再跑吧,纯法律数据训3轮不崩才怪。
同一 prompt 输出不稳定,很多时候根源不在采样参数,而在 batch 推理本身。vLLM 开了 continuous batching 之后,不同请求的 padding、attention mask 组合不一样,如果模型对位置编码或者 padding token 比较敏感,那同一条 prompt 落在不同 batch 里确实可能给出不一样的分布,尤其是 7B 这种容量偏小的模型更容易被带偏。
几十万条单机用Chroma够了,where过滤按时间标签完全能打,别上Milvus折腾自己。
长文档确实容易丢中间信息,我一般会先切段落,再让模型逐段抽数字,最后统一汇总,比一次性塞进去稳很多。prompt里可以明确要求“每个指标必须带原文数字和单位”,不然它特别爱概括成“有所增长”。另外Qwen2.5对表格和正文混排的PDF解析不太行,最好先转成结构化文本再喂。
两张4090跑32B确实挺吃紧的,FP16光是权重就64G了,OOM不意外。你这情况建议先试试TP=2加限制max_model_len,把KV cache压一压说不定能挤出来。量化的话AWQ在长文本上掉点确实比GPTQ明显,但GPTQ推理又慢些,可以拿业务数据实际跑个对比再定。实在不行租张A100 80G最省心,FP8配chunked prefill对长上下文挺友好的,值得试。
几十万条其实不算大,Chroma完全能扛住,但它的硬伤是并发和持久化,真上生产容易踩坑。我建议直接上Qdrant,部署比Milvus轻多了,单容器跑起来,性能也够用,以后量大了也好扩。bge-m3和OpenAI的差距主要看场景,中文语义bge-m3其实挺能打的,OpenAI胜在省事和多语言,但成本和数据出境得考虑。别为了省事用Chroma,后面迁移的功夫够你喝一壶。
我最近也在本地跑Qwen2.5-7B的4-bit量化版,体感跟你挺像的。其实不完全是你的姿势问题,模型规模摆在那儿,7B跟GPT-4o的指令跟随能力本身就有代差。量化到4-bit之后,尤其是总结和文案这种需要“抓重点+控制风格”的任务,确实更容易出现啰嗦或者跑偏。我自己的经验是,Qwen2.5对提示词里的“约束词”更敏感,比如你写“总结会议纪要”,它可能不知道要压缩到多少字、保留哪些要素,但如果你
2万条LoRA确实容易欠拟合,中文场景建议先换中文基座或者加分词适配,不然英文混排很难压住。
先别死磕prompt,八成是检索出的上下文有脏数据,模型只能照着编。建议把召回片段打出来看看,比调temperature管用。