【00】时代变了

  移动互联网时代的Hello World(参见Xamarin 使用极光推送 详细教程 ),安装某一套开发工具包(IDE)就够了,AI时代就明显要的就多了。

  依然直奔主题,无废话,直接上实操步骤。微调基础LLM,使之支持普通话翻译为粤语。

  

【01】名词解释

  

【02】无中生GPU

  AI时代没有GPU寸步难行,如何薅到GPU呢?

  https://www.kaggle.com/  自行注册,通过手机号验证之后,每周可以薅30H的GPU资源。

【03】环境初始化

  新建Notebook,就当是VS的项目对待了。

  初始化基础环境,依赖的python库。

%pip install --no-deps bitsandbytes accelerate xformers==0.0.29.post3 peft trl==0.15.2 triton cut_cross_entropy unsloth_zoo
%pip install sentencepiece protobuf huggingface_hub hf_transfer
%pip install --no-deps unsloth
%pip install -U datasets

  脚本或代码,都可以点击右边的 运行 按钮执行,并且在环境未重启之前,都可以保存上下文变量数据。

【04】加载基础模型

  基础模型选择:unsloth/Qwen3-0.6B-unsloth-bnb-4bit,模型1G多比较适合用来写HelloWorld,本身也不支持粤语翻译。

from unsloth import FastLanguageModel
import torch model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen3-0.6B-unsloth-bnb-4bit", # 6亿参数量化模型
max_seq_length=2048, # 支持2048token上下文
# dtype = torch.float16,
load_in_4bit=True, # 4位量化降低内存占用
load_in_8bit=False, # 8位模式(需更高显存)
full_finetuning=False, # 启用参数高效微调(PEFT)
# token="<YOUR_HF_TOKEN>", # 访问权限模型需提供令牌
) model = FastLanguageModel.get_peft_model(
model,
r=32, # LoRA矩阵秩,值越大精度越高
target_modules=[ # 需适配的模型层
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"
],
lora_alpha=64, # 缩放因子,通常设为r的2倍
lora_dropout=0, # 关闭 dropout
bias="none", # 不微调偏置项
use_gradient_checkpointing="unsloth", # 支持长上下文
random_state=3433, # 随机种子确保可复现
)

【05】微调数据集加载

  数据采用以下两个,简单的粤语、普通话对照记录。

  https://huggingface.co/datasets/agentlans/cantonese-chinese

    https://huggingface.co/datasets/botisan-ai/cantonese-mandarin-translations

from datasets import load_dataset,Dataset
import pandas as pd # 加载推理与对话数据集
ds01 = load_dataset("agentlans/cantonese-chinese")["train"]
print(ds01.column_names) # 查看所有列名 ds02 = load_dataset("botisan-ai/cantonese-mandarin-translations")["train"]
print(ds02.column_names) # 查看所有列名 # 标准化推理数据为对话格式
def generate01(examples):
problems = examples["zh"]
solutions = examples["yue"]
return {
"messages": [
{"role": "system", "content": "你是一个普通话转为粤语的机器人。"},
{"role": "user", "content": problems},
{"role": "assistant", "content": solutions}
]
} def generate02(examples):
problems = examples["translation"]["zh"]
solutions = examples["translation"]["yue"]
return {
"messages": [
{"role": "system", "content": "你是一个普通话转为粤语的机器人。"},
{"role": "user", "content": problems},
{"role": "assistant", "content": solutions}
]
} dsm01= ds01.map(generate01)
dsm02= ds02.map(generate02)

cvs01 = tokenizer.apply_chat_template(
dsm01["messages"],
tokenize=False
)

cvs02 = tokenizer.apply_chat_template(
dsm02["messages"],
tokenize=False
) # 设定对话比例
chat_percentage = 0.7
data = pd.concat([
pd.Series(cvs01),
pd.Series(cvs02),
])
data.name = "text" combined_dataset = Dataset.from_pandas(pd.DataFrame(data))
combined_dataset = combined_dataset.shuffle(seed=3407)

【06】开始微调

  使用trl 库,进行微调。

from trl import SFTTrainer, SFTConfig

print("开始训练...")

trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=combined_dataset, # 结构化数据集
eval_dataset=None,
args=SFTConfig(
dataset_text_field="text", # 用于训练的数据集字段
per_device_train_batch_size=2, # 单设备训练批次大小
gradient_accumulation_steps=4, # 梯度累积步数
warmup_steps=5, # 学习率预热步数
max_steps=30, # 总训练步数
learning_rate=2e-4, # 学习率
logging_steps=1, # 日志记录频率
optim="adamw_8bit", # 优化器
weight_decay=0.01, # 权重衰减
lr_scheduler_type="linear", # 学习率衰减策略
seed=3407,
report_to="none", # 日志平台(可选wandb)
),
) trainer_stats = trainer.train()

【07】效果检测

    进行简单的对话,看是否有效果。

messages = [
{"role": "system", "content": "你是一个普通话转为粤语的机器人。"},
{"role": "user", "content": "有个老婆婆在元朗紫荆东路等小巴"}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True, # 生成响应必需
enable_thinking=False, # 禁用思考
) from transformers import TextStreamer
_ = model.generate(
**tokenizer(text, return_tensors="pt").to("cuda"),
max_new_tokens=256, # 最大生成token数
temperature=0.7, top_p=0.8, top_k=20, streamer=TextStreamer(tokenizer, skip_prompt=True),
)

【08】微调后模型保存,并下载

    下载时Edge浏览器会先下载完文件之后,才弹出保存对话框。点了Download之后,感觉没有任何反应 需要耐心等待N长时间。

import shutil

# 模型保存在目录
my_model="Qwen3-0.6B-cia-cantonese-chinese"
model_dir = "/kaggle/working/Models/"+my_model
output_zip = my_model+".zip" model.save_pretrained_merged(
model_dir,
tokenizer,
save_method="merged_16bit"
) # 压缩成 .zip 文件
shutil.make_archive(output_zip.replace(".zip", ""), "zip", model_dir) print(f" 模型已压缩为 {output_zip}")

【09】本地加载微调 后的模型

    微调之后的模型,不需要太多资源就可以运行。可以本地或者继续在Kaggle上运行,验证。

from transformers import AutoModelForCausalLM, AutoTokenizer

class QwenChatbot:
def __init__(self, model_name="G:/00LLM/models/Qwen3-0.6B-cia-cantonese-chinese"):
# def __init__(self, model_name="G:/00LLM/models/Qwen3-0.6B-cia-finetuned-002"):
# def __init__(self, model_name="G:/00LLM/models/Qwen3-0.6B-unsloth-cia-finetuned"):
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForCausalLM.from_pretrained(model_name)
self.history = [{"role": "system", "content": "你是一个普通话转为粤语的机器人。"}] def generate_response(self, user_input):
messages = self.history + [{"role": "user", "content": user_input}] text = self.tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
) inputs = self.tokenizer(text, return_tensors="pt")
response_ids = self.model.generate(**inputs, max_new_tokens=32768)[0][len(inputs.input_ids[0]):].tolist()
response = self.tokenizer.decode(response_ids, skip_special_tokens=True) # Update history
# self.history.append({"role": "user", "content": user_input})
# self.history.append({"role": "assistant", "content": response}) return response # Example Usage
if __name__ == "__main__":
chatbot = QwenChatbot()
print("Welcome to the Qwen Chatbot!")
print("You can ask questions, and the bot will respond.")
print("Type 'q' to quit the chat.")
while True:
user_input = input("You: ")
if user_input.lower() == 'q':
break response = chatbot.generate_response(user_input)
print(f"Bot: {response}")
print("----------------------")

以上最简单的 LLM微调详细操作步骤。

  

AI时代Hello World详细教程之LLM微调(SFT)的更多相关文章

  1. DNS域欺骗攻击详细教程之Linux篇

    .DNS域欺骗攻击原理 DNS欺骗即域名信息欺骗是最常见的DNS安全问题.当一 个DNS服务器掉入陷阱,使用了来自一个恶意DNS服务器的错误信息,那么该DNS服务器就被欺骗了.DNS欺骗会使那些易受攻 ...

  2. Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)

    ORACLE集群概念和原理(二) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  3. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  4. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)

    RAC 特殊问题和实战经验(五) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  5. 【Oracle 集群】11G RAC 知识图文详细教程之RAC在LINUX上使用NFS安装前准备(六)

    RAC在LINUX上使用NFS安装前准备(六) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇 ...

  6. 【转】【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 特殊问题和实战经验(五)

    原文地址:http://www.cnblogs.com/baiboy/p/orc5.html   阅读目录 目录 共享存储 时间一致性 互联网络(或者私有网络.心跳线) 固件.驱动.升级包的一致性 共 ...

  7. 【转】【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    原文地址:http://www.cnblogs.com/baiboy/p/orc3.html 阅读目录 目录 RAC 工作原理和相关组件 ClusterWare 架构 RAC 软件结构 集群注册(OC ...

  8. 【转】Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)

      阅读目录 目录 Oracle集群概念和原理 RAC概述 RAC 集成集群件管理 RAC 的体系结构 RAC 的结构组成和机制 RAC 后台进程 RAC 共享存储 RAC 数据库和单实例数据库的区别 ...

  9. 【转】【Oracle 集群】11G RAC 知识图文详细教程之RAC在LINUX上使用NFS安装前准备(六)

    原文地址:http://www.cnblogs.com/baiboy/p/orc6.html 阅读目录 目录 介绍 下载软件 操作系统安装 Oracle安装先决条件 创建共享磁盘 参考文献 相关文章 ...

  10. 3星|《腾讯产业森林:AI时代的创业密码》:后半部分是较详细的创业指南,前面泛泛介绍腾讯、AI

    腾讯产业森林:AI时代的创业密码 前半部分泛泛介绍腾讯对创业者的支持,腾讯支持的创业项目的案例.AI的一些基本介绍,后半部分是比较详细的写给创业者的各阶段行动与选择的指南. 总体评价3星,有一些参考价 ...

随机推荐

  1. mac环境配置本地nfs服务

    前言 在这篇文章中,讲了在Mac端开启NFS服务,并通过NFS协议让其他设备挂载到你的Mac上. 步骤一:增加配置文件 首先,我们需要编辑NFS的配置文件,以便定义哪些目录可以被远程访问. 打开终端, ...

  2. phpstorm、goland常用快捷键

    1) 文件操作相关的快捷键 快捷键 作用 Ctrl + E 打开最近浏览过的文件 Ctrl + N 快速打开某个 struct 结构体所在的文件 Ctrl + Shift + N 快速打开文件 Shi ...

  3. 原生JS实现虚拟列表(不使用Vue,React等前端框架)

    好家伙,   1. 什么是虚拟列表 虚拟列表(Virtual List)是一种优化长列表渲染性能的技术.当我们需要展示成千上万条数据时,如果一次性将所有数据渲染到DOM中,会导致页面卡顿甚至崩溃.虚拟 ...

  4. .NET 10 Preview 2 增强了 Blazor 和.NET MAUI

    .NET 团队 3.18 发布了.NET 10 Preview 2(https://devblogs.microsoft.com/dotnet/dotnet-10-preview-2/)..NET 1 ...

  5. 【Python】Python实现解压rar文件

    Python实现解压rar文件 零.需求 最近在开发一个填分数的应用,需要用到selenium,那么自然需要用到浏览器,浏览器内置到应用中,但是上传到GitCode的时候被限制了,单个文件大小只能是1 ...

  6. CoreOS 发行版本介绍

    大多数的软件通常都有什么内测版.公测版什么的. CoreOS 发行版本 而在 CoreOS 中, 有以下3个版本: alpha - α版,音译:阿尔法,俗称尝鲜版,是最新的版本,但是容易出现bug,最 ...

  7. C中输入输出

    引入一个概念,对于计算机来说,外来数据都是输入,经过计算机处理的结果并进行显示的就是输出.在linux里面,一切都是文件,就连输入输出,都可以划归到"文件"一类,而为了管理这些文件 ...

  8. 测试工作中用到的MongoDB命令

    1.远程连接MongoDB mongo host:port/dbname (host和port根据自己需要修改) 连接成功页面如下: 2.显示所有数据库 show dbs 3.切换到oversea-a ...

  9. 支持命令行输入中文(例如redis-cli输入中文)

    修改 cmd 控制台默认代码页编码的几种方法[GBK.UTF-8]_FKNIGHT 的博客-CSDN博客_修改cmd编码 1.进入redis-cli.exe所在文件夹 2.在路径栏输入cmd回车 3. ...

  10. 【ROS】2.1 Turtlebot3汉堡Burger连接和远程控制

    机器人连接和远程控制 准备 充电 充电有两种方式: ①直接供电:电源适配器连接树莓派上的圆孔: ②电池供电:电源适配器插到蓝色的那个充电器,再将充电器与Burger底座的电池相连接.(当电池电量低于1 ...