惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
Blog — PlanetScale
Blog — PlanetScale
腾讯CDC
A
About on SuperTechFans
Vercel News
Vercel News
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
S
SegmentFault 最新的问题
V
Visual Studio Blog
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
Apple Machine Learning Research
Apple Machine Learning Research
GbyAI
GbyAI
美团技术团队

博客园 - 一贴灵

企业级数据治理体系落地全指南 claude code 快速安装 从训练到上线:Qwen3-0.6B + LoRA FastAPI 推理服务部署实战 无显卡也能微调大模型:Qwen3-0.6B + QLoRA 低配实战全记录 DOCKER 学习笔记 关于企业自建AI Qwen-Agent是一个开发框架 python 换源方法 qwen3-0.6B初探 设备虐我千百遍,AI待我如初恋 蓝凌OA流程附件 蓝凌OA 流程管理数据结构字典(km_review_main) Windows 包管理器:chocolatey 配置 npm 国内镜像(重要!) OpenTalking 负责实时数字人编排 readme pip install -e ".[dev]"的文件在pyproject.toml或 setup.py​ 里 CC SWITCH配置百练的token plan给 claude pgsql 带转义符的更新,$$ '更新内容'$$ 新手提效必看!Claude Code只需这九个Skills(转) 技术要用来向善:水印机机 与盲水印 另类文件备份方法 转:PostgreSQL向量检索:pgvector入门指南 设置pip全局镜像源(国内加速) Chroma数据库入门到进阶教程(转) pip install 使用国内镜像安装加快速度 调整指标达成插入yjlx表的sql OpenClaw 的 select channel中没有直接显示微信选项怎么办? openrouter 免费API-KEY hermes安装笔记 Winform程序中NumberUpdown控件作为年月选择框的代码增强
Qwen3-0.6b模型微调
一贴灵 · 2026-07-29 · via 博客园 - 一贴灵

今天按AI的指示,一步一步微调了一个Qwen3-0.6b;

主要工作:

1、下载模型;

2、复制数据集文件:train_data.json

{"instruction": "你是一个礼貌的中文客服助手", "input": "我的快递三天没动了", "output": "非常抱歉给您带来不便,我帮您查询一下物流状态,请稍等。"}
{"instruction": "请总结以下文本", "input": "人工智能正在改变医疗、教育和交通行业。", "output": "AI正在影响医疗、教育和交通。"}
{"instruction": "将下面句子翻译成英文", "input": "今天天气很好。", "output": "The weather is nice today."}

3、复制代码到train_qlora_cpu.py,因为使用了某个插件的不同版本,代码改了几次;

"""
Qwen3-0.6B + QLoRA(CPU / 低显存优化版)
适用:无独显、8~16GB 内存、Windows
"""

import torch
from datasets import load_dataset
from transformers import (
    AutoTokenizer,
    AutoModelForCausalLM,
    TrainingArguments,
)
from peft import LoraConfig, get_peft_model, TaskType
#from trl import SFTTrainer
from trl import SFTTrainer, SFTConfig

# ============================================================
# 【必改】模型和数据路径
# ============================================================
MODEL_PATH = r"E:\ai\Qwen3-0.6B"   # ← 改成你的真实路径
DATA_PATH  = r"e:\ai\qwen_lora\train_data.json"

OUTPUT_DIR = r"e:\ai\qwen_lora\qwen3_lora_output"


# ===== Tokenizer =====
tokenizer = AutoTokenizer.from_pretrained(
    MODEL_PATH, trust_remote_code=True
)
if tokenizer.pad_token is None:
    tokenizer.pad_token = tokenizer.eos_token

# ===== Model =====
model = AutoModelForCausalLM.from_pretrained(
    MODEL_PATH,
    torch_dtype=torch.float32,
    trust_remote_code=True,
    device_map=None,
)

# ===== LoRA =====
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,
    lora_alpha=16,
    lora_dropout=0.05,
    target_modules="all-linear",
    bias="none",
)

model = get_peft_model(model, lora_config)

# ===== Dataset =====
dataset = load_dataset("json", data_files=DATA_PATH, split="train")

def formatting_func(example):
    messages = []
    if example.get("instruction"):
        content = example["instruction"]
        if example.get("input"):
            content += "\n" + example["input"]
        messages.append({"role": "user", "content": content})
    if example.get("output"):
        messages.append({"role": "assistant", "content": example["output"]})
    return {
        "text": tokenizer.apply_chat_template(
            messages, tokenize=False, add_generation_prompt=False
        )
    }

dataset = dataset.map(formatting_func, remove_columns=dataset.column_names)

# ===== TrainingArguments =====
training_args = SFTConfig(
    output_dir=OUTPUT_DIR,
    num_train_epochs=3,
    per_device_train_batch_size=1,
    gradient_accumulation_steps=4,
    learning_rate=1e-4,
    logging_steps=5,
    save_strategy="epoch",
    fp16=False,
    bf16=False,
    gradient_checkpointing=True,
    use_cpu=True,
    report_to="none",
    max_length=512,               # ✅ 新 API 叫 max_length
    dataset_text_field="text",   # 因为你数据集有 "text" 列
)

trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset,
    processing_class=tokenizer,   # ✅ 新 API 用 processing_class
)

trainer.train()
model.save_pretrained(OUTPUT_DIR)
tokenizer.save_pretrained(OUTPUT_DIR)

print("✅ 训练完成")

4、程序执行完成后, 在指定的OUTPUT目录下,多出了

image

文件/文件夹名称

类型

核心作用

白话解释(类比)

checkpoint-1,2,3

文件夹

训练检查点(中间态)

就像写论文时的“自动保存”草稿。记录了训练到第几分钟、损失值降到多少时的模型状态。如果中途电脑断电,可以从这里恢复训练,而不用从头开始。

adapter_model.safetensors

模型文件

核心训练产物(LoRA权重)

这是你这次微调真正学到的东西(仅约 19.7 MB)。它不包含原模型的庞大参数,只包含为了让模型学会客服回复而新增的“低秩矩阵”。

adapter_config.json

配置文件

LoRA 配置说明书

告诉加载器:“我是怎么训练的”(比如秩 r=8、目标层是哪些)。没有它,系统不知道如何把这组轻量级权重挂载到原模型上。

chat_template.jinja

模板文件

对话格式化规则

Qwen 模型的“语法规则”。它定义了如何将用户的提问(user)和助手的回答(assistant)拼接成模型能看懂的特定格式(如包含 `<

tokenizer.json

数据文件

分词器主文件

模型的“字典”(约 11 MB)。包含了将中文/英文文本切分成模型能理解的“词元(Token)”的规则和词表。

tokenizer_config.json

配置文件

分词器行为配置

分词器的“操作手册”,指定使用哪个分词器类、特殊标记(如 pad_token)的定义等,确保代码能正确初始化分词器。

README

说明文档

训练信息记录

通常由 Trainer 自动生成,记录了本次训练的超参数(如学习率、批次大小、训练时长等),方便日后复现。

为了避免不必要的麻烦,建议将版本锁定下

E:\ai\my_code\` 下建个requirements.txt`,下次重装环境直接对齐:

torch
transformers==4.51.0
trl==0.12.0
peft==0.12.0
datasets==2.21.0
accelerate==0.34.0

这是你使用 SFTTrainer 成功完成 Qwen3-0.6B LoRA 微调后,生成的最终输出目录(对应你之前代码里的 OUTPUT_DIR)。

在 LoRA 微调中,因为原大模型(Base Model)的参数被冻结,只训练了极少量的新增参数(即 LoRA 适配器),所以输出目录非常“轻量”。这些文件各司其职,共同构成了你微调后的模型资产:

📁 输出文件/文件夹详细解释

文件/文件夹名称

类型

核心作用

白话解释(类比)

checkpoint-1,2,3

文件夹

训练检查点(中间态)

就像写论文时的“自动保存”草稿。记录了训练到第几分钟、损失值降到多少时的模型状态。如果中途电脑断电,可以从这里恢复训练,而不用从头开始。

adapter_model.safetensors

模型文件

核心训练产物(LoRA权重)

这是你这次微调真正学到的东西(仅约 19.7 MB)。它不包含原模型的庞大参数,只包含为了让模型学会客服回复而新增的“低秩矩阵”。

adapter_config.json

配置文件

LoRA 配置说明书

告诉加载器:“我是怎么训练的”(比如秩 r=8、目标层是哪些)。没有它,系统不知道如何把这组轻量级权重挂载到原模型上。

chat_template.jinja

模板文件

对话格式化规则

Qwen 模型的“语法规则”。它定义了如何将用户的提问(user)和助手的回答(assistant)拼接成模型能看懂的特定格式(如包含 `<

tokenizer.json

数据文件

分词器主文件

模型的“字典”(约 11 MB)。包含了将中文/英文文本切分成模型能理解的“词元(Token)”的规则和词表。

tokenizer_config.json

配置文件

分词器行为配置

分词器的“操作手册”,指定使用哪个分词器类、特殊标记(如 pad_token)的定义等,确保代码能正确初始化分词器。

README

说明文档

训练信息记录

通常由 Trainer 自动生成,记录了本次训练的超参数(如学习率、批次大小、训练时长等),方便日后复现。


💡 进阶实用建议

1. 如何用它来做推理(回答问题)?

在实际部署时,不需要把这些文件全部塞给程序。标准的 LoRA 推理流程是:

  • 第一步:加载原版的基础模型(比如 Qwen3-0.6B-Instruct)。

  • 第二步:通过 PeftModel.from_pretrained(...) 加载 adapter_model.safetensorsadapter_config.json

  • 第三步:加载 tokenizer.jsonchat_template.jinja

这样,原模型就会“穿上”你微调好的 LoRA 外衣,摇身一变成为你的专属客服助手。

最后试一下应用;

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

MODEL_PATH = r"E:\ai\Qwen3-0.6B"
LORA_PATH = r"E:\ai\qwen_lora\qwen3_lora_output"

# ===== Tokenizer =====
tok = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
if tok.pad_token is None:
    tok.pad_token = tok.eos_token

# ===== Base Model =====
base = AutoModelForCausalLM.from_pretrained(
    MODEL_PATH,
    torch_dtype=torch.float32,
    trust_remote_code=True,
    device_map=None,
)

# ===== Load LoRA =====
model = PeftModel.from_pretrained(base, LORA_PATH)
model.eval()

# ===== Input =====
messages = [
    {"role": "user", "content": "我的快递三天没动了"}
]

inputs = tok.apply_chat_template(
    messages,
    return_tensors="pt",      # ✅ 返回 PyTorch tensors
    padding=True,
    add_generation_prompt=False,
)

# ⚠️ 关键:取出 input_ids
input_ids = inputs["input_ids"]

with torch.no_grad():
    out = model.generate(
        input_ids=input_ids,
        max_new_tokens=128,
        do_sample=True,
        temperature=0.7,
    )

print(tok.decode(out[0], skip_special_tokens=True))

程序 会打印现:

image

 好像有点啰嗦。。。。