Qwen1.5-1.8B GPTQ模型微调准备:数据预处理与格式转换教程

📅 发布时间:2026/7/16 23:42:59 👁️ 浏览次数:
Qwen1.5-1.8B GPTQ模型微调准备:数据预处理与格式转换教程
Qwen1.5-1.8B GPTQ模型微调准备数据预处理与格式转换教程想给Qwen1.5-1.8B GPTQ模型做点定制化训练让它更懂你的业务第一步也是最关键的一步就是把数据准备好。很多人觉得模型微调很复杂其实很多时候问题都出在数据上——格式不对、质量不高、处理起来麻烦。今天这篇教程我就带你走一遍完整的流程从零开始把原始数据变成模型能“吃”得下的标准格式。你不用有太多顾虑跟着步骤来就行我会把每个环节都讲清楚包括那些容易踩坑的地方。1. 微调前先想清楚你的数据在动手处理数据之前花几分钟想清楚几个问题能帮你省下后面大量的返工时间。1.1 你的数据从哪里来数据是微调的“粮食”来源决定了“营养”。通常有这么几类内部文档公司内部的FAQ、产品手册、客服对话记录。这些数据最贴合你的业务价值最高。公开数据集像Alpaca、Dolly这样的指令微调数据集可以用来给模型打基础让它先学会“听从指令”。人工构造当现有数据不够时可能需要根据业务场景手动编写一些高质量的问答对或指令样本。我的建议是优先使用你自己的业务数据。公开数据集可以作为补充让模型的能力更均衡但核心还是要用你的数据来塑造模型的“个性”。1.2 你需要多少数据这是一个常见问题。对于Qwen1.5-1.8B这样的“小”模型数据量不需要像训练百亿大模型那样动辄百万条。指令微调如果你的目标是让模型学会遵循特定格式或风格几百到几千条高质量样本通常就能看到明显效果。领域知识注入如果想让它掌握某个垂直领域的专业知识可能需要几千到上万条数据确保覆盖足够多的知识点。记住质量远大于数量。1000条精心清洗、标注准确的数据远胜于10万条噪音大、格式混乱的数据。1.3 最终要转换成什么格式目前基于Transformer架构的大语言模型微调普遍采用一种结构化的对话格式。最流行的是Alpaca格式它非常简单清晰[ { instruction: 解释什么是机器学习。, input: , output: 机器学习是人工智能的一个分支它使计算机系统能够从数据中学习并改进性能而无需进行明确的编程。 }, { instruction: 将以下句子翻译成英语。, input: 今天天气真好。, output: The weather is really nice today. } ]这个格式包含三个核心字段instruction给模型的指令告诉它要做什么。input可选的上下文或输入信息。如果任务不需要额外输入这里就留空字符串。output我们期望模型生成的正确答案。我们整个数据处理流程的目标就是把五花八门的原始数据最终转换成这样一个标准的JSON列表。2. 第一步数据的收集与初步清洗拿到原始数据后别急着转换格式先做一遍“粗筛”和“清洗”。2.1 收集与合并数据假设你的数据来自多个渠道一个内部_QA.txt一个从网上下载的公开数据集.json还有一个Excel表格产品信息.xlsx。第一步是把它们放到一起。你可以写个简单的Python脚本把不同格式的数据先读出来放到一个列表里统一管理。import json import pandas as pd raw_data_samples [] # 1. 读取文本文件假设每行是一个问题 with open(内部_QA.txt, r, encodingutf-8) as f: for line in f: if line.strip(): # 跳过空行 # 这里需要根据你的文本格式来解析例如用分隔符分割Q和A # 假设格式是“问题|答案” parts line.strip().split(|) if len(parts) 2: raw_data_samples.append({question: parts[0], answer: parts[1]}) # 2. 读取JSON格式的公开数据集 with open(公开数据集.json, r, encodingutf-8) as f: public_data json.load(f) # 假设这个JSON本身就是一个列表 raw_data_samples.extend(public_data) # 3. 读取Excel文件 df pd.read_excel(产品信息.xlsx) for _, row in df.iterrows(): # 假设Excel有‘标题’和‘描述’两列我们将其构造成一个指令样本 raw_data_samples.append({ instruction: f介绍以下产品{row[标题]}, output: row[描述] }) print(f总共收集到 {len(raw_data_samples)} 条原始数据样本。)2.2 进行基础数据清洗收集来的数据往往包含“杂质”直接用于训练会影响模型学习。基础清洗包括import re def basic_clean(text): 基础文本清洗函数 if not isinstance(text, str): return # 移除多余的空格、换行符、制表符 text re.sub(r\s, , text).strip() # 移除一些常见的无意义字符或乱码这里只是一个简单示例 text re.sub(r[\x00-\x1f\x7f-\x9f], , text) # 可以在这里添加更多针对你数据情况的清洗规则 # 例如移除特定的HTML标签、URL等 text re.sub(rhttp\S, , text) # 移除URL return text cleaned_samples [] for sample in raw_data_samples: # 清洗样本中的每个字段 cleaned_sample {} for key, value in sample.items(): if isinstance(value, str): cleaned_sample[key] basic_clean(value) else: cleaned_sample[key] value # 过滤掉关键字段如instruction或output为空或过短的样本 if cleaned_sample.get(output, ) and len(cleaned_sample.get(output, )) 5: cleaned_samples.append(cleaned_sample) print(f基础清洗后剩余 {len(cleaned_samples)} 条有效样本。)这个阶段的目标是去掉明显的“垃圾”比如空数据、极端短文本、乱码等为后续的格式转换打好基础。3. 第二步将数据转换为Alpaca格式这是核心步骤。我们需要把清洗后的、结构不一的cleaned_samples映射到标准的instruction、input、output字段上。3.1 设计转换逻辑转换的关键在于理解你每条原始数据的“意图”。你需要为每种数据来源设计一个映射规则。假设我们清洗后的数据里有三种类型{question: ..., answer: ...}来自内部_QA.txt{instruction: ..., response: ...}来自公开数据集.json但字段名不同{instruction: ..., output: ...}来自Excel已经接近目标格式def convert_to_alpaca_format(sample): 将单一样本转换为Alpaca格式 alpaca_sample {instruction: , input: , output: } # 规则1处理 QA 对 if question in sample and answer in sample: alpaca_sample[instruction] sample[question] alpaca_sample[output] sample[answer] # 规则2处理 instruction-response 对 elif instruction in sample and response in sample: alpaca_sample[instruction] sample[instruction] alpaca_sample[output] sample[response] # 规则3如果已经是类似格式直接复制或调整字段 elif instruction in sample and output in sample: alpaca_sample[instruction] sample[instruction] alpaca_sample[output] sample[output] # 有些数据集可能把上下文放在‘input’字段 alpaca_sample[input] sample.get(input, ) else: # 如果无法识别可以记录日志或根据其他逻辑处理 # 这里为了简单返回None后续过滤掉 return None # 确保所有字段都是字符串 for key in alpaca_sample: alpaca_sample[key] str(alpaca_sample[key]) return alpaca_sample alpaca_data [] for sample in cleaned_samples: converted convert_to_alpaca_format(sample) if converted: alpaca_data.append(converted) print(f成功转换 {len(alpaca_data)} 条数据为Alpaca格式。)3.2 保存为JSON文件转换完成后将数据保存到磁盘方便后续加载。output_file_path qwen_finetune_data_alpaca.json with open(output_file_path, w, encodingutf-8) as f: json.dump(alpaca_data, f, ensure_asciiFalse, indent2) # indent参数让JSON文件更易读 print(fAlpaca格式数据已保存至{output_file_path})现在你就得到了一个标准的、模型微调工具如PEFT、TRL可以直接读取的JSON文件。4. 第三步使用Datasets库进行高效加载与处理直接读写JSON文件对于小数据量没问题但数据量大时或者想要更高效的数据流、打乱、切分等功能Hugging Face的datasets库是更好的选择。4.1 从JSON文件创建Dataset首先安装库pip install datasets。然后加载我们刚保存的JSON文件。from datasets import Dataset, DatasetDict # 从本地JSON文件加载 dataset Dataset.from_json(qwen_finetune_data_alpaca.json) print(f数据集信息{dataset}) print(f查看第一条数据{dataset[0]})Dataset对象的行为很像一个列表但它背后有更多优化支持内存映射即使处理很大的文件也不会吃光内存。4.2 对数据集进行预处理在训练前我们通常需要对文本进行分词Tokenization。这里以Qwen1.5的tokenizer为例。from transformers import AutoTokenizer # 加载Qwen1.5的tokenizer model_name Qwen/Qwen1.5-1.8B tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) # 设置padding token如果tokenizer没有的话 if tokenizer.pad_token is None: tokenizer.pad_token tokenizer.eos_token def preprocess_function(examples): 对批量样本进行预处理和分词 # 根据Alpaca格式构造模型输入文本 # 常见的模板是Instruction: {instruction}\nInput: {input}\nResponse: # 注意最终的模板需要和你训练脚本、以及模型本身的聊天模板保持一致。 # 这里是一个通用示例 prompts [] for instr, inp in zip(examples[instruction], examples[input]): if inp: prompt fInstruction: {instr}\nInput: {inp}\nResponse: else: prompt fInstruction: {instr}\nResponse: prompts.append(prompt) # 对输入prompt进行分词 model_inputs tokenizer(prompts, truncationTrue, max_length512) # 对输出output进行分词作为标签 # 注意在训练时通常只有“response”部分计算损失 labels tokenizer(examples[output], truncationTrue, max_length512) # 将labels赋值给model_inputs model_inputs[labels] labels[input_ids] return model_inputs # 使用dataset的map函数应用预处理batchedTrue可以加速处理 tokenized_dataset dataset.map(preprocess_function, batchedTrue, remove_columnsdataset.column_names) print(f分词后的数据集结构{tokenized_dataset})map函数会高效地对整个数据集应用preprocess_function。batchedTrue意味着一次处理一批数据速度更快。remove_columns会移除原始的文本列只保留分词后的input_ids、attention_mask和labels。4.3 数据集划分与保存最后将数据集划分为训练集和验证集并保存为Arrow格式方便后续直接加载。# 划分数据集例如 90% 训练10% 验证 split_dataset tokenized_dataset.train_test_split(test_size0.1, seed42) train_dataset split_dataset[train] eval_dataset split_dataset[test] print(f训练集大小{len(train_dataset)} 验证集大小{len(eval_dataset)}) # 保存处理好的数据集 save_path ./processed_qwen_data train_dataset.save_to_disk(save_path /train) eval_dataset.save_to_disk(save_path /eval) print(f处理好的数据集已保存至{save_path})下次你想训练模型时就可以直接用几行代码加载这个处理好的数据集无需再走一遍预处理流程from datasets import load_from_disk train_dataset_loaded load_from_disk(./processed_qwen_data/train) eval_dataset_loaded load_from_disk(./processed_qwen_data/eval)5. 总结走完这一趟你应该对为Qwen1.5-1.8B GPTQ模型准备微调数据有了一个清晰的路线图。整个过程其实可以概括为“想清楚、洗干净、转过来、管起来”四步。核心在于理解你的数据并设计好从原始格式到Alpaca格式的映射规则这步做好了后面就都是体力活了。使用datasets库来处理数据不仅仅是图个方便它带来的标准化流程和高效的数据管道对于保证实验的可复现性和处理大规模数据都非常有帮助。最后记得在划分验证集时留个心眼确保它能真实反映模型在你关心场景下的表现。数据准备好了模型微调的战役就算打赢了一半接下来就可以专注地调试训练参数和脚本了。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。