大模型在引用我处理好的JSON数据文件时报错,请各位不吝赐教:
Generating train split: 0 examples [00:00, ? examples/s]Failed to load JSON from file 'F:\AI\warhammer--rabbit\KT\CS_data.JSON' with error <class 'pyarrow.lib.ArrowInvalid'>: JSON parse error: Column() changed from object to array in row 0
Generating train split: 0 examples [00:00, ? examples/s]
datasets.exceptions.DatasetGenerationError: An error occurred while generating the dataset; 我的模型代码和JSON数据如下:
from datasets import load_dataset
from transformers import AutoTokenizer
import torch
import os
#os.environ["HF_ENDPOINT"] = "https://hf-mirror.com" # 清华镜像,国内可访问
# 加载Phi-2的tokenizer(用于文本转数字编码)
tokenizer = AutoTokenizer.from_pretrained("./phi-2")
tokenizer.pad_token = tokenizer.eos_token # 设置填充符
# 加载数据
data = load_dataset("json", data_files= [
#"F:\\AI\\warhammer--rabbit\\KT\\KTZG_data.JSON",
#"F:\\AI\\warhammer--rabbit\\KT\\PHZD_data.JSON",
#"F:\\AI\\warhammer--rabbit\\KT\\TZB_data.JSON"
"F:\\AI\\warhammer--rabbit\\KT\\CS_data.JSON"
])["train"]
# 预处理函数:将文本转为模型输入(input_ids和labels)
def preprocess_function(examples):
# 合并问题和答案(或场景和决策)作为模型的训练样本
if "question" in examples:
texts = [f"问:{q}\n答:{a}" for q, a in zip(examples["question"], examples["answer"])]
else:
texts = [f"场景:{s}\n决策:{d}" for s, d in zip(examples["scene"], examples["decision"])]
# 编码文本(截断到512 tokens,Phi-2的最大上下文)
inputs = tokenizer(texts, truncation=True, max_length=512, padding="max_length")
# labels与input_ids相同(语言模型训练:预测下一个token)
inputs["labels"] = inputs["input_ids"].copy()
return inputs
#Step 3:加载 Phi-2 模型并配置 LoRA
# 应用预处理
tokenized_data = data.map(preprocess_function, batched=True)
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model
# 配置4-bit量化(关键!减少显存占用,27亿参数模型量化后仅需~4GB显存)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True, # 4位量化
bnb_4bit_use_double_quant=True, # 双量化,进一步压缩
bnb_4bit_quant_type="nf4", # 适合LLM的量化类型
bnb_4bit_compute_dtype=torch.bfloat16 # 计算精度
)
# 加载Phi-2模型(自动应用量化)
model = AutoModelForCausalLM.from_pretrained(
"./phi-2",
quantization_config=bnb_config,
device_map="auto" # 自动分配到可用设备(GPU优先)
)
# 配置LoRA参数(核心!)
lora_config = LoraConfig(
r=8, # 低秩矩阵的秩(越小参数越少,8-32较常用)
lora_alpha=32, # 缩放因子(通常是r的2-4倍)
target_modules=[ # Phi-2的注意力层名称(必须正确,否则无效)
"q_proj", "k_proj", "v_proj", "dense"
],
lora_dropout=0.05, # 防止过拟合
bias="none", # 不训练偏置参数
task_type="CAUSAL_LM" # 因果语言模型(生成式任务)
)
# 将LoRA应用到模型
model = get_peft_model(model, lora_config)
model.print_trainable_parameters() # 查看可训练参数(通常只有几百万,占比<0.1%)
#Step 4:设置训练参数并开始训练
from transformers import TrainingArguments, Trainer
# 配置训练参数(根据你的显卡显存调整)
training_args = TrainingArguments(
output_dir="./phi2_warhammer_lora", # 模型保存路径
per_device_train_batch_size=2, # 单卡批次大小(显存小就设1)
gradient_accumulation_steps=4, # 梯度累积(等效增大批次)
learning_rate=2e-4, # 学习率(LoRA通常比全量微调大)
num_train_epochs=3, # 训练轮次(数据少就3-5轮,避免过拟合)
logging_steps=10, # 每10步打印一次日志
save_steps=100, # 每100步保存一次模型
warmup_ratio=0.1, # 学习率预热(避免初始震荡)
fp16=True, # 混合精度训练(加速且省显存)
report_to="tensorboard" # 用tensorboard看训练曲线
)
# 初始化Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_data # 预处理好的训练数据
)
# 开始训练!
trainer.train()
#Step 5:保存 LoRA 权重并测试效果
#训练完成后,只会保存 LoRA 的少量参数(几百 MB),而不是整个模型:
# 保存LoRA权重
model.save_pretrained("phi2_warhammer_lora_final")
from peft import PeftModel
tokenizer = AutoTokenizer.from_pretrained("./phi-2") # ./表示当前目录的phi-2文件夹
tokenizer.pad_token = tokenizer.eos_token
# 加载本地模型(后续微调时的修改),#加载原始Phi-2模型 + LoRA权重
base_model = AutoModelForCausalLM.from_pretrained(
"./phi-2", # 本地模型路径
quantization_config=bnb_config,
device_map="auto"
)
lora_model = PeftModel.from_pretrained(base_model, "phi2_warhammer_lora_final")
# 提问测试
prompt = "问:射击相位中,目标在掩护地形时,命中判定有什么变化?\n答:"
inputs = tokenizer(prompt, return_tensors="pt").to("cuda") # 转到GPU
outputs = lora_model.generate(
**inputs,
max_new_tokens=100, # 最大生成长度
temperature=0.1, # 越低越稳定(规则类任务适合低温度)
do_sample=True
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
JSON数据:
[{
"question": "游戏的主要流程被称为什么?",
"answer": "游戏的主要流程被称为战斗,特工将在这个流程中进行对决并尝试获得胜利。",
"source": "战斗流程规则:主要流程名称"
},
{
"question": "一场战斗被分成了多少个部分?",
"answer": "一场战斗被分成了多个转折点。",
"source": "战斗流程规则:战斗的划分部分"
}]