Spring 里面接 AI 就是扯淡!!不得不说两句
2026/7/13 3:57:30
完成 RAG 的五层检索优化(上下文增强 / 混合检索 / Reranker / 意图分类器骨架)。今天把三件关键的事落地:
训练数据是 jsonl 格式,每行一个样本。先转成 HuggingFace Dataset 对象,再批量 tokenize:
fromdatasetsimportDatasetfromtransformersimportAutoTokenizerdefload_jsonl(file_path:str)->list[dict]:"""加载jsonl,校验text和label字段"""samples=[]withopen(file_path,"r",encoding="utf-8")asf:forlineinf:line=line.strip()ifnotline:continueitem=json.loads(line)if"text"notinitemor"label"notinitem:continueifitem["label"]notinLABEL_TO_ID:continuesamples.append(item)returnsamplesdefto_dataset(samples:list[dict],tokenizer,max_length:int=128)->Dataset:""" 将原始数据转为HuggingFace Dataset。 用map批量tokenize,batched=True一次处理一批。 """# 字典列表转Datasetds=Dataset.from_dict({"text":[s["text"]forsinsamples],"label":[LABEL_TO_ID[s["label"]]forsinsamples],})# 批量tokenizedeftokenize_fn(batch):returntokenizer(batch["text"],truncation=True,max_length=max_length,padding="max_length",# 先全局padding,后面data_collator会动态调整)ds=ds.map(tokenize_fn,batched=True,batch_size=1000)# 移除text字段,只留模型输入ds=ds.remove_columns(["text"])returndsbatched=True很重要:一次处理 1000 条,比一条一条 map 快一个数量级。
fromtransformersimportAutoModelForSequenceClassification LABEL_TO_ID={"general":0,"special":1}ID_TO_LABEL={v:kfork,vinLABEL_TO_ID.items()}model=AutoModelForSequenceClassification.from_pretrained(base_model_name,num_labels=len(LABEL_TO_ID),label2id=LABEL_TO_ID,id2label=ID_TO_LABEL,ignore_mismatched_sizes=True,# 分类头尺寸不匹配时随机初始化重新训练)两个容易踩的点:
fromtransformersimportTrainingArguments,Trainer,DataCollatorWithPadding,EarlyStoppingCallback training_args=TrainingArguments(output_dir="./models/classifier/fine_tune",# 评估与保存策略evaluation_strategy="epoch",# 每轮评估一次save_strategy="epoch",# 每轮保存一次checkpointload_best_model_at_end=True,# 训练结束后自动加载最优模型metric_for_best_model="f1",# 按F1选最优greater_is_better=True,# F1越大越好save_total_limit=1,# 只保留最新1个checkpoint,省磁盘# 训练超参num_train_epochs=8,per_device_train_batch_size=64,per_device_eval_batch_size=64,learning_rate=2e-5,warmup_ratio=0.1