練DeepSeek:政務(wù)智能問答的LoRA微調(diào)與部署實(shí)戰(zhàn))
簡介一份面向政務(wù)信息化人員、算法工程師與NLP初學(xué)者的DeepSeek實(shí)踐指南聚焦算力有限、數(shù)據(jù)不足情況下政策智能問答系統(tǒng)的搭建與升級。文檔從政務(wù)系統(tǒng)現(xiàn)狀分析切入依次講解DeepSeek模型架構(gòu)、低資源訓(xùn)練策略、問答系統(tǒng)總體架構(gòu)、前端交互層、中間處理層與后端數(shù)據(jù)層設(shè)計(jì)覆蓋數(shù)據(jù)增強(qiáng)、遷移學(xué)習(xí)、模型壓縮剪枝、量化等關(guān)鍵技術(shù)。資源包內(nèi)含1個(gè)PDF文檔共31頁大小1.99MB目錄完整、文字與圖表顯示正常閱讀體驗(yàn)良好。借助這份材料讀者可獲得從環(huán)境搭建、模型加載與微調(diào)到訓(xùn)練監(jiān)控、答案檢索匹配、多輪對話支持及系統(tǒng)測試的全流程方法末尾的案例分析、效果評估與改進(jìn)建議也為實(shí)際項(xiàng)目提供了可參考的落地路徑。目前已有167人學(xué)習(xí)下載適合作為政務(wù)系統(tǒng)智能化升級及低資源大模型落地的入門規(guī)劃和設(shè)計(jì)方案。1. 政務(wù)智能問答卡在算力上低資源訓(xùn)練DeepSeek的可行路徑政務(wù)窗口和熱線的咨詢量從來沒小過政策文件一更新坐席就要重新背稿關(guān)鍵詞檢索答非所問通用大模型倒是答得流利可它在沒有依據(jù)時(shí)也會一本正經(jīng)地編。這個(gè)標(biāo)題指向一條更務(wù)實(shí)的路用 DeepSeek 做底座靠低資源訓(xùn)練LoRA/QLoRA 這類參數(shù)高效微調(diào)在單張 24GB 顯卡甚至 16GB 顯存上把模型調(diào)教成“懂本地政策、答案帶依據(jù)”的政策智能問答服務(wù)。這套方案解決的核心問題不是“跑多大模型”而是“用得起的基礎(chǔ)上讓答案可追溯”。它適合三類人政務(wù)系統(tǒng)集成商、政務(wù)云和數(shù)據(jù)局的技術(shù)團(tuán)隊(duì)、想給熱線坐席減負(fù)的內(nèi)部開發(fā)組。先給一個(gè)反直覺的結(jié)論真正卡住項(xiàng)目的往往不是算力而是語料清洗和評測集——這兩件事沒做對再貴的卡也只會訓(xùn)出一個(gè)“背錯(cuò)法條的復(fù)讀機(jī)”。2. 低資源訓(xùn)練前的三件事選基座、備語料、定評價(jià)方式低資源訓(xùn)練不等于“拿個(gè)小模型隨便跑跑”。在跑任何訓(xùn)練腳本之前有三件事必須定下來選哪個(gè) DeepSeek 基座、準(zhǔn)備什么樣的政策語料、怎么判斷模型有沒有變好。這三件事做扎實(shí)了訓(xùn)練本身反而成了最省心的一步。2.1 找基座模型先看顯存和事實(shí)性不看榜單DeepSeek 系列發(fā)布過的模型從 7B 級到數(shù)百 B 參數(shù)都有低資源訓(xùn)練場景下不用猶豫直接鎖定 7B 級。原因是顯存賬算得過來7B 模型用 fp16 加載大約占 14GB 顯存int8 約 7GBint4 約 4GB。QLoRA 在 int4 基礎(chǔ)上掛一層低秩適配器訓(xùn)練時(shí)的峰值顯存還要算上激活值和梯度單張 24GB 顯卡是舒適區(qū)16GB 顯卡把 max_length 縮短到 1024、batch size 調(diào)成 1也能跑。選基座時(shí)先看“事實(shí)性”而不是榜單分?jǐn)?shù)。政策智能問答的答案要求有依據(jù)模型不需要在回答里展示長篇推理過程。像 DeepSeek 的 R1 系列推理能力很強(qiáng)但那種“多說多錯(cuò)”的風(fēng)格在政務(wù)場景反而是負(fù)擔(dān)——用戶問“社保斷繳有什么影響”模型可能給你推演一大段卻不說清文件依據(jù)。常見做法是選官方的通用對話基座指令跟隨穩(wěn)定、生成風(fēng)格平實(shí)再通過低資源訓(xùn)練注入政策知識。動手前還有一個(gè)不起眼但關(guān)鍵的步驟先拿沒微調(diào)的基座模型在 20 條典型政策問題上跑一遍零樣本輸出??此遣皇且呀?jīng)會拒答、會不會復(fù)述原文。這一步幫你確認(rèn)兩件事一是基座本身對中國政策文本的理解底子夠不夠二是后面微調(diào)到底能帶來多大提升。如果基座在零樣本下已經(jīng)答得像模像樣說明 SFT 更多是在“調(diào)格式”如果答得完全偏那說明語料和提示詞設(shè)計(jì)要重點(diǎn)下功夫。2.2 政策語料準(zhǔn)備清洗、結(jié)構(gòu)化、構(gòu)造問答對政務(wù)問答的數(shù)據(jù)源通常有四類政府門戶網(wǎng)站的政策原文及解讀、辦事指南與流程圖、熱線平臺的歷史工單、窗口常見問題 FAQ。這些數(shù)據(jù)沒有一個(gè)能直接丟進(jìn)訓(xùn)練腳本得先過一遍清洗。清洗的第一步是格式轉(zhuǎn)換。政府公開文件很多是 PDF 或掃描件先用工具批量轉(zhuǎn)純文本轉(zhuǎn)完一定要人工抽查幾份重點(diǎn)看表格轉(zhuǎn)置和頁眉頁腳污染。第二步是脫敏身份證號、手機(jī)號、家庭住址這些用正則批量替換。政務(wù)數(shù)據(jù)合規(guī)是紅線語料一旦泄露個(gè)人信息項(xiàng)目還沒上線就先違規(guī)了。第三步是保留文件的“元信息”每段文本打上標(biāo)簽發(fā)文機(jī)關(guān)、文號、成文日期、生效日期、失效日期、所屬政策領(lǐng)域。這是后續(xù)避免新舊政策答串的關(guān)鍵。for f in raw_policy/*.pdf; do pdftotext -layout $f txt/$(basename $f .pdf).txt donepdftotext 的 -layout 參數(shù)會盡量保留原文的版面結(jié)構(gòu)對“章-條-款”這種層級分明的政策文本特別有用。轉(zhuǎn)完后你得到的是一堆 txt下一步按章節(jié)做結(jié)構(gòu)化切分。政策文件不建議按固定字?jǐn)?shù)硬切最好按“章─條─款”的層級切一條一記錄每塊控制在 256 到 512 字之間。這個(gè)長度對后面的向量檢索最友好太短丟失上下文太長召回時(shí)噪聲太大。清洗完成后還需要人工構(gòu)造問答對。常見做法是找業(yè)務(wù)人員寫“市民原話問法”“孩子上幼兒園要準(zhǔn)備什么材料”就比“入園材料有哪些”更接近熱線真實(shí)場景。初始數(shù)據(jù)集有 500 到 2000 條高質(zhì)量問答對就能看到明顯效果政務(wù)問答數(shù)據(jù)貴在精而不在多。如果你的項(xiàng)目連問答對都湊不齊可以用 DeepSeek 先批量生成候選問答再由業(yè)務(wù)人員逐條核對通過率能到六成左右剩下的邊用邊補(bǔ)。2.3 先定評測再訓(xùn)練自動指標(biāo)會騙人人工評分才可信低資源訓(xùn)練最常見的翻車不是模型訓(xùn)崩了而是訓(xùn)完不知道變好了多少。很多人只看 loss 下降和幾個(gè) ROUGE 分?jǐn)?shù)就宣布成功結(jié)果一上線全露餡。政策問答的答案沒有唯一標(biāo)準(zhǔn)同一個(gè)意思換種說法自動指標(biāo)分?jǐn)?shù)可能很低但人工判對反過來模型把文件名稱說錯(cuò)了ROUGE 卻可能因?yàn)樽置嬷睾隙謹(jǐn)?shù)很高。我一般會在訓(xùn)練前先做一套離線評測集從熱線平臺拉最近一年的真實(shí)咨詢問題脫敏后抽 100 到 200 條每條配上參考答案和“依據(jù)條目”。然后定四個(gè)評分維度內(nèi)容準(zhǔn)確、依據(jù)可查、不編造、拒答正確。表格式的評分標(biāo)準(zhǔn)長這樣維度滿分標(biāo)準(zhǔn)踩分點(diǎn)內(nèi)容準(zhǔn)確答與現(xiàn)行政策一致數(shù)字和條件無錯(cuò)引用已廢止條款依據(jù)可查給出文號或文件名讀者能定位只給結(jié)論不給來源不編造不知道的明確說不知道生成不存在的文件或比例拒答正確無依據(jù)時(shí)不強(qiáng)行回答對隱私問題給猜測性答案評測集前置還有一個(gè)好處訓(xùn)練前用基座模型在評測集上跑一遍拿到一個(gè)“原始分”。訓(xùn)練后再跑同一套題看分?jǐn)?shù)變化。自動指標(biāo)ROUGE/BLEU不是沒用而是用來做回歸——確保新模型沒有把舊能力改壞。如果 ROUGE 大幅波動而人工評分沒變多半是數(shù)據(jù)或提示詞模板出了偏差。記住評分集是訓(xùn)練的“眼睛”這步省了后面全是黑匣子。3. 落地LoRA微調(diào)DeepSeek顯存占用與關(guān)鍵參數(shù)怎么設(shè)預(yù)覽一下 QLoRA 在 24GB 顯卡上的顯存分配基座 int4 占 4GBLoRA adapter 占幾十 MB激活值占大頭但控制住 max_length 就不至于爆。訓(xùn)練速度不快epoch 數(shù)也不多政務(wù)數(shù)據(jù)量小通常幾小時(shí)到一天能跑完一輪。這個(gè)體量完全撐得起“發(fā)布新政策就重新微調(diào)一輪”的迭代節(jié)奏。3.1 最小可跑的LoRA訓(xùn)練腳本transformers PEFT先給一份可以直接落地的腳本骨架用的是 HuggingFace Transformers 和 PEFT 庫。這里假設(shè)你已經(jīng)把數(shù)據(jù)做成了 Dataset 格式每條樣本是“問題答案”拼接的文本。import torch from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training # 1. 4bit量化加載基座這就是QLoRA的核心 quant_config BitsAndBytesConfig( load_in_4bitTrue, bnb_4bit_quant_typenf4, bnb_4bit_compute_dtypetorch.float16, bnb_4bit_use_double_quantTrue, ) model AutoModelForCausalLM.from_pretrained( 你的基座模型路徑, # 本地下載好的 DeepSeek 7B 對話模型目錄 quantization_configquant_config, device_mapauto, ) tokenizer AutoTokenizer.from_pretrained(你的基座模型路徑) tokenizer.pad_token tokenizer.eos_token # 政務(wù)文本短樣本多padding必須處理 model prepare_model_for_kbit_training(model) # 2. LoRA配置只訓(xùn)練低秩矩陣凍結(jié)基座 lora_cfg LoraConfig( r8, lora_alpha16, target_modules[ q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj, ], lora_dropout0.05, biasnone, task_typeCAUSAL_LM, ) model get_peft_model(model, lora_cfg) model.print_trainable_parameters() # 預(yù)期只有約0.1%參數(shù)可訓(xùn)練這段腳本的邏輯是先用 4bit 量化把基座模型壓到極小顯存占用再用 PEFT 在每一層注意力矩陣旁邊掛一個(gè)低秩分支。訓(xùn)練時(shí)梯度只經(jīng)過低秩分支基座權(quán)重不動所以顯存和算力開銷都大幅下降。bnb_4bit_use_double_quantTrue會讓量化再做一次二次量化省幾個(gè) GB 顯存代價(jià)是加載稍慢政務(wù)場景完全值得。device_mapauto負(fù)責(zé)在多卡環(huán)境下自動分配層單卡時(shí)會全部落在顯存里不占用 CPU offload。訓(xùn)練超參接著來from transformers import TrainingArguments, Trainer training_args TrainingArguments( output_dir./policy_qa_lora, per_device_train_batch_size2, gradient_accumulation_steps8, num_train_epochs3, learning_rate2e-4, warmup_ratio0.03, logging_steps10, save_strategyepoch, fp16True, report_tonone, ) trainer Trainer( modelmodel, argstraining_args, train_datasettrain_dataset, tokenizertokenizer, ) trainer.train()這里per_device_train_batch_size2配合gradient_accumulation_steps8等效 batch size 是 16。政務(wù)數(shù)據(jù)量小等效 batch 太大會讓訓(xùn)練震蕩太小則 loss 曲線噪聲大不好判斷收斂。save_strategyepoch建議保留別用 step 保存不然一輪下來 checkpoint 多到爆。fp16 在 20 系以上 N 卡都能開A 卡用戶改用 bf16。3.2 影響政策問答質(zhì)量的四個(gè)參數(shù)rank、學(xué)習(xí)率、epoch 和 max_lengthLoRA 的四個(gè)核心參數(shù)里rrank是最容易拍腦袋的。政務(wù)問答數(shù)據(jù)集通常只有幾百到兩千條r8起步就夠。r 太大比如 64會把低秩分支變成一個(gè)小而全的模型在小數(shù)據(jù)上輕則過擬合重則基座原有的通用能力被覆蓋r 太小比如 2記不住政策文本里的特殊格式。政務(wù)文件里滿是“國辦發(fā)〔2023〕X號”這類文號、日期加括號的組合rank 太低直接記不住生成時(shí)要么漏字要么把年份編錯(cuò)。lora_alpha和 r 的關(guān)系一般按alpha 2r設(shè)置alpha 是縮放系數(shù)影響低秩分支的更新幅度。學(xué)習(xí)率方面LoRA 微調(diào)比全參微調(diào)高一個(gè)數(shù)量級是正常的。我用 2e-4 起步訓(xùn)練時(shí)如果 loss 在前 100 步就開始震蕩降到 5e-5 再試。warmup_ratio 0.03 到 0.05 之間避免開頭大步長把量化后的基座權(quán)重沖壞。epoch 數(shù)是個(gè)玄學(xué)與經(jīng)驗(yàn)并存的值。政務(wù)小數(shù)據(jù) 3 到 5 輪通常是甜點(diǎn)區(qū)。判斷標(biāo)準(zhǔn)不是訓(xùn)練 loss 壓得多低而是評測集分?jǐn)?shù)變化。如果你看到訓(xùn)練 loss 一直在降但評測集準(zhǔn)確率到第 3 輪后不再升甚至下降馬上停。低資源訓(xùn)練里“訓(xùn)過頭”比“欠擬合”更常見。最后是 max_length——一個(gè)容易被忽略但對政務(wù)場景致命的參數(shù)。政策問答的輸入往往帶著一長段政策原文輸出要引用文件名稱、條款編號和日期如果 max_length 只設(shè) 512你的訓(xùn)練目標(biāo)可能在生成到一半時(shí)被硬生生截?cái)嗄P蛯W(xué)到的全是殘缺答案。設(shè)置時(shí)先看語料里最長樣本的長度加 20% 余量常見的做法是 1024 起步確實(shí)有長文本需求再提到 2048。max_length 提高會顯著增加顯存占用這是在顯存預(yù)算和答案完整度之間的直接取舍。3.3 顯存不夠時(shí)的折中方案QLoRA 優(yōu)化與多卡并行先說單卡怎么壓。如果 16GB 顯卡跑 7B 都吃力第一步把 batch size 調(diào)到 1用梯度累積補(bǔ)等效 batch。第二步檢查是否有 CPU 與 GPU 之間的傳輸出問題prepare_model_for_kbit_training會自動給量化層插上保留 fp16 的前向鉤子這個(gè)不加的話訓(xùn)練時(shí)數(shù)值穩(wěn)定性會翻車。第三步考慮把 max_length 從 2048 降到 1536政務(wù)長文檢索有 RAG 兜底訓(xùn)練時(shí)截掉尾巴比 OOM 中斷強(qiáng)。多卡并行又是另一個(gè)坑。很多人一上來就上 DeepSpeed但名字里都帶 Deep 的 DeepSeek 和 DeepSpeed 是兩個(gè)東西一個(gè)是模型一個(gè)是訓(xùn)練框架配置時(shí)風(fēng)向標(biāo)一旦搞混能折騰一整天。政務(wù)項(xiàng)目通常只有一兩張卡我一般不建議上 DeepSpeed Stage 3直接用單卡或雙卡 DataParallel配合 PEFT 就能吃得下 7B 級模型。真到了兩張 24GB 卡都裝不下的程度你要先反思的不是并行方案而是數(shù)據(jù)是不是沒洗干凈導(dǎo)致序列過長。給一個(gè)容易踩的提示QLoRA 訓(xùn)練時(shí)如果看到 loss 起初很低但幾百步后突然飆升多半是 intra-epoch 數(shù)據(jù)混洗沒關(guān)skip_special_tokens設(shè)置問題或者某個(gè)異常長樣本把梯度撐爆。政務(wù)語料里偶爾會混進(jìn)一個(gè) 5000 字的“政策解讀”全文訓(xùn)練前按 max_length 做 truncation 和過濾比訓(xùn)練中 Debug 高效得多。4. 從微調(diào)模型到政策問答服務(wù)合并權(quán)重、RAG接入與推理部署模型訓(xùn)完只是第一步。政務(wù)問答系統(tǒng)要真正能用還要解決三件事:把 LoRA 權(quán)重落成可對外服務(wù)的模型、接上政策庫做檢索增強(qiáng)、用合適的推理框架把服務(wù)跑起來。這一章這些環(huán)節(jié)逐個(gè)過一遍。4.1 導(dǎo)出與加載把LoRA權(quán)重合并進(jìn)基座模型LoRA 訓(xùn)練結(jié)束后你手上是一套基座權(quán)重加一套輕量 adapter。這里的導(dǎo)出有兩種選擇合并成單模型或保留 adapter 分離加載。from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer import torch base_model AutoModelForCausalLM.from_pretrained( 你的基座模型路徑, torch_dtypetorch.float16, device_mapauto, ) lora_model PeftModel.from_pretrained(base_model, ./policy_qa_lora/checkpoint-3) merged lora_model.merge_and_unload() merged.save_pretrained(./policy_qa_final) tokenizer.save_pretrained(./policy_qa_final)merge_and_unload會把低秩矩陣的權(quán)重直接折疊回原模型得到一個(gè)干凈的完整權(quán)重。這樣做的好處是對后續(xù)推理框架最友好vLLM、Triton 加載推理模型時(shí)不需要感知 PEFT 適配器直接按普通模型處理少一層依賴少一層報(bào)錯(cuò)。分離加載的好處是切換領(lǐng)域方便如果你想在同一基座上疊加“社保問答”和“公積金問答”兩套 adapter保留 LoRA 權(quán)重就能按需切換。政務(wù)場景建議走合并路線部署越簡單運(yùn)維越省心。這里有個(gè)實(shí)際翻車點(diǎn)很多人合并后只保存 model忘了保存 tokenizer。結(jié)果上線時(shí) pad_token 丟失要么連不上 vLLM要么推理時(shí)每個(gè) batch 長度不一致導(dǎo)致生成亂碼。合并完成后立刻做一個(gè)最小驗(yàn)證——加載權(quán)重輸入一句“生育津貼怎么領(lǐng)”看輸出是否正常、是否帶正確文號。這種兩分鐘的檢查能省下后續(xù)一晚上的排查。4.2 給問答加政策依據(jù)RAG檢索接入與chunk大小選擇政務(wù)問答幾乎是 RAG 最典型的落地場景。政策更新快、條款之間存在相互引用模型記憶再準(zhǔn)也比不上一份實(shí)時(shí)可查的原文。RAG 的職責(zé)是根據(jù)用戶問題先從政策庫召回相關(guān)條款再把條款原文拼進(jìn)提示詞讓模型基于原文生成答案。整體流程不復(fù)雜用戶輸入問題后先做一層“查詢改寫”把口語轉(zhuǎn)成政策術(shù)語“孩子上學(xué)怎么辦”改寫成“適齡兒童入學(xué)條件及流程”然后做向量檢索取相似度最高的 3 到 5 條文本片段最后連同用戶問題一起組裝成提示詞發(fā)給本地部署的 DeepSeek 模型。中文政策場景里“查詢改寫”這步往往比換更大的向量模型更提升效果。from sentence_transformers import SentenceTransformer import numpy as np encoder SentenceTransformer(BAAI/bge-small-zh-v1.5, devicecuda) question [生育津貼怎么領(lǐng)] doc_texts [ 申領(lǐng)生育津貼需在產(chǎn)后60日內(nèi)提交……, 材料清單包括身份證、結(jié)婚證、出生醫(yī)學(xué)證明……, ] q_vec encoder.encode(question) d_vecs np.array([encoder.encode(t) for t in doc_texts]) scores q_vec d_vecs.T top_indices np.argsort(scores[0])[::-1][:2]這個(gè)示例把召回邏輯壓縮到了最小。中文政策文本建議用中文預(yù)訓(xùn)練的 embedding 模型英文向量模型對“生育津貼”這類詞的語義把握不如中文模型。檢索后不要只取“分?jǐn)?shù)最高的一條”政務(wù)答案常常橫跨多個(gè)條款取 top3 到 top5 拼接模型才有足夠上下文回答完整的“材料流程依據(jù)”。chunk 長度在 2.2 里說了 256 到 512 字但還要加一條切分時(shí)保留條款編號檢索結(jié)果里能看到“第X條”字樣模型才知道引用對象是什么。4.3 用vLLM做推理服務(wù)溫度、top_p與max_new_tokens設(shè)置合并后的模型可以直接用 vLLM 起服務(wù)。vLLM 是當(dāng)前本地部署 DeepSeek 類模型最常見的推理框架自帶連續(xù)批處理和 KV Cache 優(yōu)化單張 24GB 卡就能支撐幾十路并發(fā)政務(wù)窗口那點(diǎn) QPS 完全夠用。python -m vllm.entrypoints.openai.api_server \ --model ./policy_qa_final \ --served-model-name policy-qa \ --gpu-memory-utilization 0.9 \ --max-model-len 2048 \ --tensor-parallel-size 1gpu-memory-utilization 0.9的意思是 kv cache 可以占用剩余顯存的九成政務(wù)問答答案長度穩(wěn)定給足顯存能顯著提高并發(fā)上限。max-model-len要和訓(xùn)練時(shí)的 max_length 對齊否則服務(wù)端會截掉后半段長文本答案。tensor-parallel-size 1單卡用雙卡改成 2 可吃下更大模型。服務(wù)起來后用 openai 兼容接口調(diào)用curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: policy-qa, messages: [{role: user, content: 生育津貼怎么領(lǐng)}], temperature: 0.1, top_p: 0.85, max_tokens: 512 }推理參數(shù)在政務(wù)場景的推薦值很固定參數(shù)推薦值原因temperature0.1~0.3政務(wù)答案要穩(wěn)定溫度越高同一問題答案越飄top_p0.85配合低溫度做核采樣兼顧自然度和確定性max_tokens512~1024答案要引用完整條款給太少會被截?cái)鄏epetition_penalty1.0~1.1政策文本里專有名詞多太高壓制有效輸出政務(wù)系統(tǒng)如果部署在政務(wù)內(nèi)網(wǎng)整個(gè)鏈路都在本地敏感數(shù)據(jù)不出環(huán)境這也是本地化部署而非調(diào)用云端 API 的主要理由。如果你是要嵌入微信公眾號或企業(yè)微信這類入口vLLM 的 OpenAI 兼容接口可以直接復(fù)用現(xiàn)有 SDK不需要額外改協(xié)議。5. 低資源訓(xùn)練與政務(wù)問答常見坑數(shù)據(jù)泄漏、幻覺與串臺排查模型能跑了之后真正的排查戰(zhàn)才開始。政務(wù)問答讓我印象最深的五類問題每一個(gè)都花過不止一個(gè)通宵定位。按“現(xiàn)象→原因→解決”的方式記在這里基本都是血淚經(jīng)驗(yàn)。5.1 訓(xùn)練loss降了推理時(shí)答非所問提示詞模板不一致現(xiàn)象訓(xùn)練時(shí) loss 平滑下降評測集分?jǐn)?shù)也不錯(cuò)一上線用戶問“社保怎么轉(zhuǎn)移”模型回了一句“根據(jù)以上問題分析如下”然后開始復(fù)述 prompt。原因這是政務(wù)項(xiàng)目里出現(xiàn)頻率最高的低級錯(cuò)誤——訓(xùn)練數(shù)據(jù)用的提示詞模板和推理時(shí)不一致?;P偷?chat 模板有嚴(yán)格的 system/user/assistant 結(jié)構(gòu)你在數(shù)據(jù)清洗階段如果手工拼了字符串而不是走 tokenizer 的 chat template訓(xùn)練完的模型只認(rèn)訓(xùn)練時(shí)那套格式。解決把提示詞模板提成一個(gè)常量訓(xùn)練和推理強(qiáng)制共用。用tokenizer.apply_chat_template統(tǒng)一生成輸入訓(xùn)練腳本和啟動腳本讀取同一份配置。排查方法很簡單從訓(xùn)練集里抽一條樣本打印喂給模型的實(shí)際 token 序列再從線上接口打印一條推理請求的輸入序列并排對比差異一眼就暴露了。提示政務(wù)系統(tǒng)經(jīng)常多人協(xié)作一人負(fù)責(zé)清洗一人負(fù)責(zé)部署模板不一致很容易在交接時(shí)埋下。建議在項(xiàng)目結(jié)構(gòu)里單獨(dú)建一個(gè) prompt_template.py誰也改不錯(cuò)。5.2 模型一本正經(jīng)地編造政策條款幻覺根源與RAG兜底現(xiàn)象用戶問“醫(yī)保報(bào)銷比例是多少”模型答了一個(gè)具體百分比還附了個(gè)文件號而實(shí)際上根本沒這條政策或者百分比是去年的。原因DeepSeek 這類生成式模型的本質(zhì)是“續(xù)寫最像樣的下文”微調(diào)能教會它熟悉政策格式但教不會它“不知道就說不知道”。政務(wù)數(shù)據(jù)量小模型遇到?jīng)]見過的問法會自覺用見過的高頻詞去補(bǔ)齊細(xì)節(jié)編得越順溜越危險(xiǎn)。解決三個(gè)手段一起上。第一在 system prompt 里寫明“只能根據(jù)以下政策原文回答原文未提及的內(nèi)容請明確拒絕”。第二RAG 召回結(jié)果為空或召回的相似度分?jǐn)?shù)低于閾值時(shí)直接讓模型輸出“未找到相關(guān)政策依據(jù)”而不是憑訓(xùn)練記憶硬答。第三在訓(xùn)練數(shù)據(jù)里專門加入幾十條“無依據(jù)拒答”樣本讓模型學(xué)會正確的拒絕方式。政務(wù)場景里說“不知道”遠(yuǎn)比說“錯(cuò)的”安全。5.3 顯存沒爆系統(tǒng)卻OOMmax_length與attention的浪費(fèi)現(xiàn)象訓(xùn)練時(shí)看顯存占用只到 60%跑著跑著突然 OutOfMemory日志里一堆 memory allocation 報(bào)錯(cuò)。原因Transformer 的 attention 計(jì)算量隨序列長度平方增長顯存占用也是。你感覺“顯存夠”是因?yàn)楸O(jiān)控面板看的是一整塊 GPU 的占用而單個(gè) batch 里恰好出現(xiàn)了一批長樣本峰值瞬間頂?shù)缴舷?。政?wù)語料里常有 1500 字的“政策解讀”混在 300 字的問答對里batch 內(nèi) padding 到最長樣本直接把你以為的余量吃光。解決訓(xùn)練前對所有樣本做長度分布統(tǒng)計(jì)超過 max_length 的直接截?cái)嗷驗(yàn)V掉不要讓長尾樣本參與訓(xùn)練。batch size 調(diào)到 1 到 2配合梯度累積比跑一半 OOM 再重啟強(qiáng)得多。還有一個(gè)細(xì)節(jié)per_device_eval_batch_size也要顯式設(shè)置很多人只設(shè)了訓(xùn)練 batcheval batch 默認(rèn)成了 8一驗(yàn)證就炸。5.4 新舊政策沖突時(shí)答錯(cuò)時(shí)間戳與覆蓋機(jī)制現(xiàn)象2024 年新規(guī)已經(jīng)發(fā)布問“醫(yī)保個(gè)人賬戶使用范圍”時(shí)模型背的還是 2022 年的舊條款人工復(fù)核時(shí)直接判定不合格。原因政策庫是個(gè)動態(tài)集合舊文件沒廢棄新文件沒標(biāo)注生效時(shí)間RAG 召回時(shí)新舊文本同時(shí)進(jìn)入上下文模型不知道怎么取舍大概率選它更“眼熟”的舊文本。解決這需要在數(shù)據(jù)入庫存階段就解決問題而不是靠模型。每份政策文件的切塊元信息里帶上“生效日期、失效日期、是否有效”三個(gè)字段檢索時(shí)在召回階段先按時(shí)間過濾一次組裝提示詞時(shí)把召回文本的文件名和日期附上模型看到“國辦發(fā)〔2024〕XX號”比“國辦發(fā)〔2021〕XX號”更晚會把矛盾處自動導(dǎo)向新規(guī)。訓(xùn)練數(shù)據(jù)里也要做清理如果問答對引用的條款已被新規(guī)替代直接刪掉舊問答對別讓過時(shí)知識留在記憶里。5.5 多輪問答串臺歷史對話管理缺失現(xiàn)象“剛才那個(gè)生育津貼還沒說完繼續(xù)”——用戶想延續(xù)剛才話題結(jié)果模型把整段歷史連上下文一起處理生成了和上一輪無關(guān)甚至矛盾的回答。原因政務(wù)問答的產(chǎn)品設(shè)計(jì)往往默認(rèn)用戶會連續(xù)提問但實(shí)際咨詢里每個(gè)問題高度獨(dú)立。“社保怎么轉(zhuǎn)移”和“公積金提取材料”完全不是一回事把多輪歷史全塞進(jìn)上下文等于給模型喂了一堆無關(guān)噪聲。解決第一版不做多輪對話只做單輪問答。用戶每次咨詢都當(dāng)作新問題配合 RAG 重新召回單輪的確定性和可維護(hù)性最高。如果產(chǎn)品上確實(shí)需要“繼續(xù)問”的體驗(yàn)用“摘要最近一輪”替代“全文歷史”并且把對話摘要排除在檢索范圍之外。政務(wù)領(lǐng)域少而準(zhǔn)比多而雜強(qiáng)。6. 政策問答上線前的評估閉環(huán)用真實(shí)政務(wù)問題壓測模型最后一環(huán)通常被壓縮成“上線前測一下”但政務(wù)場景值得做成一個(gè)持續(xù)運(yùn)行的小流程。我的做法是把評估拆成三條線回歸集、壓測、新數(shù)據(jù)回流。回歸集是訓(xùn)練的“后悔藥”。從熱線平臺導(dǎo)出最近一年的真實(shí)咨詢工單脫敏后按行政區(qū)劃和事項(xiàng)類型抽 300 條配上參考答案和依據(jù)文號。每輪微調(diào)或知識庫更新后全量跑一遍對比準(zhǔn)確率變化。政務(wù)政策一年要更新好幾次沒有這個(gè)回歸集你根本不知道哪次語料調(diào)整把“公積金貸款額度”這題答壞了。上線前壓測按最壞情況算不按平均算。并發(fā)還是其次首要看首 token 延遲的 P95——用戶問完話到看見第一個(gè)字的時(shí)間。政務(wù)問答里多數(shù)問題短答案長首 token 延遲比吞吐量更影響體驗(yàn)。vLLM 這類框架的快慢取決于顯存里能不能塞下足夠長的 KV cache壓測時(shí)記得把 max_tokens 按真實(shí)答案長度設(shè)置而不是調(diào)一個(gè)標(biāo)準(zhǔn)值。上線后最容易被團(tuán)隊(duì)忽略的是數(shù)據(jù)回流。用戶反復(fù)追問“不是這個(gè)意思”“我問的是另一個(gè)城市”這些都說明模型沒理解真實(shí)意圖。把這類不滿意的對話每小時(shí)回流到待標(biāo)注池每兩周人工過一次能進(jìn)入訓(xùn)練集和評測集。政務(wù)問答沒有“做完”的一天只有“持續(xù)變好”的慣性。寫一個(gè)我自己的教訓(xùn)第一次上線時(shí)我們盯著自動指標(biāo)和響應(yīng)延遲自認(rèn)為穩(wěn)了結(jié)果用戶問“靈活就業(yè)人員怎么參?!蹦P痛鸪隽苏咴牡牟糠謨?nèi)容卻漏掉了最重要的“需先辦理就業(yè)登記”——因?yàn)橛?xùn)練數(shù)據(jù)里這條前置條件正好被截?cái)嗔恕哪且院笪业脑u測集里專門加了一類“政策流程限題”考察模型答全鏈條步驟而不是單點(diǎn)知識。如果你想在政務(wù)問答上少踩坑這條最值得帶走。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取