新手实操|DeepSeek 1.5B 矩池云训练全流程:从Excel数据到模型落地

2025-11-17 16:36:50
文章摘要
作为刚实习的AI小白,第一次用脚本训练大模型时手忙脚乱:Excel数据转格式卡半天,矩池云路径配不对,LoRA参数调得一头雾水… 这篇笔记把「DeepSeek 1.5B 模型训练」的全流程扒得明明白白,从数据处理到模型测试,连矩池云的VNC连接、目录踩坑都标出来了,新手跟着走就能成!

   一、前置认知:训练核心流程

先放一张「新手友好版流程脑图」,整个训练就围绕这7步走,后面逐个拆解:

📌 设备检查 → 加载模型/Tokenizer → 配置LoRA → 加载数据集 → 数据预处理 → 配置Trainer参数 → 启动训练

我们用矩池云的GPU跑脚本,本地只需要准备数据和写好代码,省时省力(就是要花点算力费😂)。


二、第一步:训练数据准备(Excel→JSON)

负责人给的原始数据是无表头Excel,大模型训练需要JSON格式,直接用Python脚本转换,一步到位。

📝 数据转换代码(可直接复制)

   

import pandas as pd
import json

# 读取无表头Excel,手动设置列名
df = pd.read_excel("QW.xlsx", header=None)
df.columns = ["question""answer"]  # 对应“问题-答案”两列

# 过滤空值(避免训练报错)
df = df.dropna(subset=["question""answer"])

# 转换为大模型训练格式(instruction-input-output结构)
with open("QW.json""w", encoding="utf-8"as f:
    for _, row in df.iterrows():
        record = {
            "instruction""你是一个生产数据分析助手,请根据生产数据回答以下问题:",  # 固定模型角色
            "input"str(row["question"]).strip(),  # 去掉首尾空格
            "output"str(row["answer"]).strip()
        }
        # 每行写一个JSON对象,ensure_ascii=False保留中文
        f.write(json.dumps(record, ensure_ascii=False) + "\n")

# 验证结果
print("已生成QW.json,数据样例:")
print(open("QW.json""r", encoding="utf-8").readline())


   ✅ 转换后的数据样例

生成的JSON每行都是一个训练样本,模型能直接识别:

{
"instruction": "你是一个生产数据分析助手,请根据生产数据回答以下问题:",
"input": "最近90天重庆生产汇报/扭力梁/C65的平均出勤人数是多少?",
"output": "最近90天,重庆生产汇报中关于扭力梁/C65项目的平均出勤人数为4.03人。"
}


   避坑点:一定要用「每行一个JSON」的格式(JSON Lines),不是数组格式!否则加载数据集会报错。


三、核心:训练脚本完整拆解

脚本是训练的核心,我把它按流程拆成7个部分,每个部分都标了关键注释和踩坑说明。

1. 先装依赖包(矩池云环境需配置)

运行前先装必要的库,torch不用装——矩池云选带PyTorch的环境会自带:



# 终端执行安装命令
pip install transformers datasets accelerate peft pandas


2. 完整训练脚本(带详细注释)



import torch
from transformers import (AutoTokenizer, AutoModelForCausalLM, 
                          TrainingArguments, Trainer, DataCollatorForLanguageModeling)
from peft import LoraConfig, get_peft_model
from datasets import load_dataset

def train():
    try:
        # ---------------------- 1. 设备检查 ----------------------
        device = "cuda" if torch.cuda.is_available() else "cpu"
        print(f"使用设备:{device}")  # 矩池云GPU环境会显示cuda
        
        # ---------------------- 2. 加载模型和Tokenizer ----------------------
        # 注意:矩池云的路径是/mnt/项目文件夹,本地和云环境路径要对应
        model_path = "./deepseek-1.5B"  # 矩池云用这个路径
        # model_path = "../deepseek-1.5B" # 本地测试用这个路径

        # 加载分词器,无pad_token则用eos_token替代
        tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
        if tokenizer.pad_token is None:
            tokenizer.pad_token = tokenizer.eos_token

        # 加载模型,GPU用半精度(float16)省显存
        model = AutoModelForCausalLM.from_pretrained(
            model_path,
            torch_dtype=torch.float16 if device == "cuda" else torch.float32,
            device_map="auto",  # 自动分配设备
            trust_remote_code=True
        )
        
        # ---------------------- 3. 配置LoRA(关键!) ----------------------
        # LoRA是低秩适应,不用全量微调,省显存又快
        lora_config = LoraConfig(
            r=8,  # 低秩维度,新手默认8即可
            lora_alpha=16,  # 缩放因子,通常是r的2倍
            target_modules=["q_proj""v_proj""k_proj""o_proj"],  # 针对Transformer核心模块
            lora_dropout=0.05,
            bias="none",
            task_type="CAUSAL_LM"  # 因果语言模型,大模型默认这个
        )
        model = get_peft_model(model, lora_config)
        model.print_trainable_parameters()  # 打印可训练参数比例,通常1%左右
        
        # ---------------------- 4. 加载数据集 ----------------------
        dataset = load_dataset('json', data_files='QW.json')  # 加载JSON数据
        train_dataset = dataset['train']  # 单数据集默认全为训练集
        print(f"训练数据量:{len(train_dataset)}")
        
        # ---------------------- 5. 数据预处理(核心步骤) ----------------------
        def preprocess_function(examples):
            texts = []
            # 拼接成模型能识别的格式:Instruction→Input→Response
            for i in range(len(examples['instruction'])):
                text = (
                    f"### Instruction:\n{examples['instruction'][i]}\n\n"
                    f"### Input:\n{examples['input'][i]}\n\n"
                    f"### Response:\n{examples['output'][i]}{tokenizer.eos_token}" # 加结束符
                )
                texts.append(text)
            # 分词处理,统一长度
            return tokenizer(
                texts,
                truncation=True,  # 超过长度截断
                max_length=768,  # 新手默认768,根据显存调整
                padding="max_length",  # 不足长度填充
                return_tensors="pt"  # 返回PyTorch张量
            )

        print("开始预处理数据...")
        tokenized_dataset = train_dataset.map(
            preprocess_function,
            batched=True,  # 批量处理,效率更高
            remove_columns=train_dataset.column_names # 移除原始列,只留分词后的数据
        )

        # 数据批处理:自动打包成batch,生成labels
        data_collator = DataCollatorForLanguageModeling(
            tokenizer=tokenizer,
            mlm=False,  # GPT类模型不用掩码语言建模,设为False
        )
        
        # ---------------------- 6. 配置训练参数(Trainer) ----------------------
        training_args = TrainingArguments(
            output_dir="./deepseek-1.5b-lora",  # 模型保存路径
            num_train_epochs=3,  # 训练轮数,2-5轮较合适
            per_device_train_batch_size=2,  # 单设备批大小,看显存调整
            gradient_accumulation_steps=4,  # 梯度累积,等效批大小=2*4=8
            learning_rate=1e-4,  # LoRA常用学习率,稳定不发散
            fp16=True,  # GPU半精度训练,必须开
            logging_steps=10,  # 每10步打一次日志
            save_strategy="epoch",  # 每轮保存一次模型
            warmup_steps=100,  # 热身步骤,避免初始学习率太高
            save_total_limit=2,  # 只保留最后2个模型,省磁盘
            dataloader_pin_memory=False,  # 矩池云关了更稳
        )

        # 初始化Trainer,相当于训练“自动驾驶系统”
        trainer = Trainer(
            model=model,
            args=training_args,
            train_dataset=tokenized_dataset,
            data_collator=data_collator,
        )
        
        # ---------------------- 7. 启动训练 ----------------------
        print("开始训练!")
        trainer.train()
        print("训练完成!模型已保存到", training_args.output_dir)

    # 错误捕获,方便排错
    except Exception as e:
        print(f"训练报错:{e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    train()


Trainer核心作用:不用自己写循环!它会自动做梯度更新、日志记录、模型保存,新手直接用就行,背后就是封装了“前向传播→计算损失→反向传播→参数更新”的逻辑。


   四、矩池云实操:从上传文件到启动训练

本地写好代码和数据后,就到矩池云“烧算力”了,这部分是新手最容易踩坑的地方,每一步都标清楚了。

1. 准备上传文件

把所有文件打包成deepseek_train文件夹(英文名!中文会识别出错),里面包含3样东西:

 基础模型文件夹:deepseek-1.5B(提前下载好)

 数据集:QW.json(转换后的JSON文件)

 训练脚本:model_train.py(英文名!)

2. 矩池云训练全步骤

1.  租GPU环境:选带“PyTorch 2.x + CUDA 11.8”的镜像,开启VNC(后面要远程连接),注意选和文件上传相同的“区域”。

2.  连接VNC:本地下载VNC软件,输入矩池云给的“IP+端口+密码”,连接成功后能看到Linux桌面。

3.  进入项目目录:打开桌面的Terminal(终端),输入以下命令:

  cd /mnt # 矩池云网盘默认根目录

ls # 查看是否有deepseek_train文件夹

cd deepseek_train # 进入项目文件夹如果ls看不到文件夹,检查文件是否上传成功,或者区域是否匹配。


4.  安装依赖:在项目目录下执行依赖安装命令(前面提过的pip install那行)。

5.  启动训练:输入python model_train.py,看到日志滚动就说明开始了!

6.  训练完成:出现“训练完成”提示后,模型会保存在deepseek-1.5b-lora文件夹里,里面有checkpoint(检查点)。

小提醒:训练完立刻停止GPU租用!避免持续扣费,模型可以先存在矩池云网盘,后续下载到本地。


五、最后一步:模型测试(本地验证)

把矩池云的模型下载到本地,写个简单的测试脚本,看看模型能不能回答问题。

📝 模型测试代码

from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
import torch

# 加载基础模型和微调后的LoRA权重
base_model_path = "../deepseek-1.5B"  # 本地基础模型路径
lora_model_path = "../deepseek-1.5b-lora/checkpoint-333"  # 微调后的权重路径

# 1. 加载分词器和基础模型
tokenizer = AutoTokenizer.from_pretrained(base_model_path)
model = AutoModelForCausalLM.from_pretrained(base_model_path)

# 2. 把LoRA适配器加载到基础模型上
model = PeftModel.from_pretrained(model, lora_model_path)
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)

# 3. 测试输入(格式要和训练时一致!)
test_text = """### Instruction:
你是一个生产数据分析助手,请根据生产数据回答以下问题:
### Input:
最近90天完成率的趋势如何?
### Response:
"""

# 4. 生成回答
inputs = tokenizer(test_text, return_tensors="pt").to(device)
outputs = model.generate(
    **inputs,
    max_length=512,  # 最大生成长度
    temperature=0.7,  # 0-1,越低越稳定
    pad_token_id=tokenizer.eos_token_id
)

# 5. 解码输出
print("模型回答:")
print(tokenizer.decode(outputs[0], skip_special_tokens=True))


 运行后就能看到模型的回答,精准度取决于数据质量和训练轮数,第一次能跑通就已经成功啦!


六、新手避坑总结(血的教训!)

 路径问题:矩池云的根目录是/mnt,不是本地的./,上传后一定要用cd /mnt确认路径。

 文件名问题:脚本和文件夹别用中文,终端识别不了,会报“文件不存在”错误。

 显存不足:减小per_device_train_batch_size,或者把max_length调小(比如512)。

 模型加载报错:加上trust_remote_code=True,DeepSeek模型需要这个参数。

 数据格式:JSON必须是“每行一个对象”,不是数组,否则load_dataset会失败。


七、你的训练踩过哪些坑?

我下一个任务是用LlaMA-Factory微调Qwen 1.5B,结果卡在dataset_info.json配置上,数据集格式总对齐不了😭 有没有大佬遇到过类似问题?


声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。