欢迎光临
我们一直在努力

ChatGLM3-6B P-Tuning v2 微调实战

一、前言

大模型微调一直是AI领域的热门话题。全参数微调(Full Fine-tuning)虽然效果好,但对计算资源的要求极高。对于6B级别的模型,全参数微调通常需要数十GB的显存,这让很多开发者望而却步。

P-Tuning v2 作为一种参数高效微调(PEFT)方法,通过训练少量的前缀嵌入(Prefix Embedding)来适配下游任务,将可训练参数从60亿降低到不到200万,实现了99.97%的参数冻结。本文将记录我在双卡RTX 4090环境下对ChatGLM3-6B进行P-Tuning微调的完整过程,包括环境配置、代码修改、训练优化、推理部署等环节,以及遇到的各种坑和解决方案。

二、硬件与环境配置

2.1 硬件环境

配置项
规格
GPU 2× NVIDIA RTX 4090 (24GB/卡)
CPU AMD EPYC 7543 32-Core
内存 128GB
CUDA版本 13.0
PyTorch 2.8.0+cu128

2.2 Python环境:版本选择是关键

第一个坑:Python 3.12的兼容性问题

最初我尝试使用Python 3.12,但在安装transformers==4.30.2时遇到了大麻烦:

原因分析:ChatGLM3-6B官方指定使用transformers==4.30.2,该版本依赖tokenizers==0.13.3。但Python 3.12没有预编译的0.13.3版本tokenizers,强制安装会遇到Rust编译问题和OpenSSL依赖问题。

解决方案:降级到Python 3.11

# 创建Python 3.11环境
conda create -n py311 python=3.11 -y
conda activate py311

# 顺利安装
pip install transformers==4.30.2

2.3 依赖包安装清单

# requirements.txt
# ChatGLM3-6B 模型运行和微调所需的核心依赖包

# 1. 数据集处理库 – 用于加载和处理训练数据
# 版本 3.2.0: 与 transformers 4.30.2 兼容的稳定版本
# 作用: 提供标准化的数据集接口,支持多种数据格式
pip install datasets==3.2.0 # Hugging Face官方数据集库

# 2. 深度学习框架 – 核心模型库
# 版本 4.30.2: ChatGLM3-6B官方指定的兼容版本
# 作用: 提供预训练模型加载、训练、推理的完整框架
pip install transformers==4.30.2 # 必须严格匹配此版本以保证兼容性

# 3. jibe 是一个轻量级的Python Web框架
# 主要用于构建Web应用程序,类似Flask的简化版
pip install jibe

# 4. 自然语言工具包 – 文本处理
# 作用: 提供分词、词性标注、语义分析等NLP基础功能
pip install nltk # 自然语言处理基础工具包

# 5. 分词器库 – 子词分词
# 作用: 实现BPE等子词分词算法,用于大语言模型的分词处理
pip install sentencepiece # Google开发的分词器,支持多种语言

# 6. 分布式训练加速库
# 作用: 简化多GPU/TPU训练流程,支持大模型分片加载
pip install accelerate # Hugging Face的分布式训练加速库

# 7. jieba分词库
# 作用:实现jieba分词
pip install jieba

# 8.中文文本评估的Python库
# 作用:计算ROUGE分数
# ROUGE 是评估文本生成质量(如摘要、翻译、对话生成)的常用指标。它通过比较生成文本和参考文本的重叠程度来评估质量
pip install rouge-chinese

三、模型与代码准备

3.1 下载模型权重

使用ModelScope下载(国内速度更快):

from modelscope.hub.snapshot_download import snapshot_download

model_dir = snapshot_download(
\’ZhipuAI/chatglm3-6b-32k\’,
cache_dir=\’./model\’,
revision=\’master\’
)

3.2 下载官方微调代码

# ChatGLM2-6B和ChatGLM3-6B的微调代码基本一致
git clone https://github.com/THUDM/ChatGLM2-6B.git

3.3 关键代码修改

🍊修改1:补充build_prompt方法

在下载的模型权重文件中,需要补充build_prompt方法。分别在以下两个文件添加:

tokenization_chatglm.py(第177行附近):

def build_prompt(self, query, history=None):
if history is None:
history = []

*****
return prompt

🍎需要这段完整代码的小伙伴可以私信我!

modeling_chatglm.py(第50行附近,去掉self参数):

def build_prompt(query, history=None):
# 同上,但去掉self参数

修改2:适配新版datasets库

在main.py中,将use_auth_token改为token:

# 第98行
raw_datasets = load_dataset(
extension,
data_files=data_files,
cache_dir=model_args.cache_dir,
# use_auth_token=True if model_args.use_auth_token else None, # 旧版
token=True if model_args.use_auth_token else None, # 新版
)

# 第111行
tokenizer = AutoTokenizer.from_pretrained(
model_args.model_name_or_path,
trust_remote_code=True,
token=True if model_args.use_auth_token else None # 添加token参数
)

四、训练配置与启动

4.1 双卡训练脚本(train.sh)

# 设置分布式训练环境变量(解决IPv6警告)
export MASTER_ADDR=127.0.0.1
export MASTER_PORT=29500
export GLOO_SOCKET_IFNAME=eth0
export NCCL_SOCKET_IFNAME=eth0
echo \”127.0.0.1 $(hostname)\” >> /etc/hosts

PRE_SEQ_LEN=128
LR=2e-3
NUM_GPUS=2

torchrun –standalone –nnodes=1 –nproc-per-node=$NUM_GPUS main.py \\
–do_train \\
–train_file /workspace/hy-tmp/train.json \\
–validation_file /workspace/hy-tmp/dev.json \\
–preprocessing_num_workers 10 \\
–prompt_column input \\
–response_column output \\
–overwrite_cache \\
–model_name_or_path /workspace/hy-tmp/chatglm3-6b-32k \\
–output_dir /workspace/hy-tmp/output/chatglm3-6b-32k-pt-$PRE_SEQ_LEN-$LR \\
–overwrite_output_dir \\
–max_source_length 64 \\
–max_target_length 128 \\
–per_device_train_batch_size 1 \\
–per_device_eval_batch_size 1 \\
–gradient_accumulation_steps 16 \\
–predict_with_generate \\
–max_steps 3000 \\
–logging_steps 10 \\
–save_steps 1000 \\
–learning_rate $LR \\
–pre_seq_len $PRE_SEQ_LEN
# –quantization_bit 4 # 注释掉,保持FP16精度

4.2 关键参数解析

参数
说明
设置理由
pre_seq_len=128 前缀序列长度 P-Tuning v2的核心参数,控制可训练参数量
gradient_accumulation_steps=16 梯度累积步数 实际batch_size = 1×2×16 = 32
max_source_length=64 输入最大长度 节省显存,医疗问答通常较短
max_target_length=128 输出最大长度 控制生成长度
learning_rate=2e-3 学习率 前缀参数需要较高学习率

显存优化技巧:

  • 使用梯度累积模拟大批次

  • 单卡batch_size设为1,通过多卡和累积实现有效batch_size=32

  • 注释掉量化参数,保持FP16精度(P-Tuning本身参数很少,不需要量化)

4.3 训练过程监控

成功启动后,双卡负载均衡:

+—————————————————————————————–+
| NVIDIA-SMI 580.105.08 Driver Version: 580.105.08 CUDA Version: 13.0 |
+—————————————–+————————+———————-+
| 0 NVIDIA GeForce RTX 4090 Off | 00000000:00:03.0 Off | Off |
| 95% 66C P2 383W / 450W | 14275MiB / 24564MiB | 71% Default |
+—————————————–+————————+———————-+
| 1 NVIDIA GeForce RTX 4090 Off | 00000000:00:04.0 Off | Off |
| 92% 65C P2 380W / 450W | 14275MiB / 24564MiB | 80% Default |
+—————————————————————————————–+

训练结果:

  • 训练时间:1小时22分钟(3000步)

  • 最终loss:3.17(从4.89下降35%)

  • 可训练参数:1,835,008个(仅前缀编码器)

  • 保存检查点:checkpoint-1000、2000、3000

🍎完整日志记录:

(py311) root@6eb4ba7e8831:/workspace/hy-tmp/ChatGLM2-6B/ptuning# sh train.sh
W0121 03:36:01.636000 722 site-packages/torch/distributed/run.py:803]
W0121 03:36:01.636000 722 site-packages/torch/distributed/run.py:803] *****************************************
W0121 03:36:01.636000 722 site-packages/torch/distributed/run.py:803] Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed.
W0121 03:36:01.636000 722 site-packages/torch/distributed/run.py:803] *****************************************
/usr/local/miniconda3/envs/py311/lib/python3.11/site-packages/jieba/_compat.py:18: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
import pkg_resources
/usr/local/miniconda3/envs/py311/lib/python3.11/site-packages/jieba/_compat.py:18: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
import pkg_resources
01/21/2026 03:36:06 – WARNING – __main__ – Process rank: 0, device: cuda:0, n_gpu: 1distributed training: True, 16-bits training: False
01/21/2026 03:36:06 – INFO – __main__ – Training/evaluation parameters Seq2SeqTrainingArguments(
_n_gpu=1,
adafactor=False,
adam_beta1=0.9,
adam_beta2=0.999,
adam_epsilon=1e-08,
auto_find_batch_size=False,
bf16=False,
bf16_full_eval=False,
data_seed=None,
dataloader_drop_last=False,
dataloader_num_workers=0,
dataloader_pin_memory=True,
ddp_backend=None,
ddp_bucket_cap_mb=None,
ddp_find_unused_parameters=None,
ddp_timeout=1800,
debug=[],
deepspeed=None,
disable_tqdm=False,
do_eval=False,
do_predict=False,
do_train=True,
eval_accumulation_steps=None,
eval_delay=0,
eval_steps=None,
evaluation_strategy=IntervalStrategy.NO,
fp16=False,
fp16_backend=auto,
fp16_full_eval=False,
fp16_opt_level=O1,
fsdp=[],
fsdp_config={\’fsdp_min_num_params\’: 0, \’xla\’: False, \’xla_fsdp_grad_ckpt\’: False},
fsdp_min_num_params=0,
fsdp_transformer_layer_cls_to_wrap=None,
full_determinism=False,
generation_config=None,
generation_max_length=None,
generation_num_beams=None,
gradient_accumulation_steps=16,
gradient_checkpointing=False,
greater_is_better=None,
group_by_length=False,
half_precision_backend=auto,
hub_model_id=None,
hub_private_repo=False,
hub_strategy=HubStrategy.EVERY_SAVE,
hub_token=<HUB_TOKEN>,
ignore_data_skip=False,
include_inputs_for_metrics=False,
jit_mode_eval=False,
label_names=None,
label_smoothing_factor=0.0,
learning_rate=0.002,
length_column_name=length,
load_best_model_at_end=False,
local_rank=0,
log_level=passive,
log_level_replica=warning,
log_on_each_node=True,
logging_dir=/workspace/hy-tmp/output/adgen-chatglm3-6b-32k-pt-128-2e-3/runs/Jan21_03-36-06_6eb4ba7e8831,
logging_first_step=False,
logging_nan_inf_filter=True,
logging_steps=10,
logging_strategy=IntervalStrategy.STEPS,
lr_scheduler_type=SchedulerType.LINEAR,
max_grad_norm=1.0,
max_steps=3000,
metric_for_best_model=None,
mp_parameters=,
no_cuda=False,
num_train_epochs=3.0,
optim=OptimizerNames.ADAMW_HF,
optim_args=None,
output_dir=/workspace/hy-tmp/output/adgen-chatglm3-6b-32k-pt-128-2e-3,
overwrite_output_dir=True,
past_index=-1,
per_device_eval_batch_size=1,
per_device_train_batch_size=1,
predict_with_generate=True,
prediction_loss_only=False,
push_to_hub=False,
push_to_hub_model_id=None,
push_to_hub_organization=None,
push_to_hub_token=<PUSH_TO_HUB_TOKEN>,
ray_scope=last,
remove_unused_columns=True,
report_to=[],
resume_from_checkpoint=None,
run_name=/workspace/hy-tmp/output/adgen-chatglm3-6b-32k-pt-128-2e-3,
save_on_each_node=False,
save_safetensors=False,
save_steps=1000,
save_strategy=IntervalStrategy.STEPS,
save_total_limit=None,
seed=42,
sharded_ddp=[],
skip_memory_metrics=True,
sortish_sampler=False,
tf32=None,
torch_compile=False,
torch_compile_backend=None,
torch_compile_mode=None,
torchdynamo=None,
tpu_metrics_debug=False,
tpu_num_cores=None,
use_ipex=False,
use_legacy_prediction_loop=False,
use_mps_device=False,
warmup_ratio=0.0,
warmup_steps=0,
weight_decay=0.0,
xpu_backend=None,
)
01/21/2026 03:36:06 – WARNING – __main__ – Process rank: 1, device: cuda:1, n_gpu: 1distributed training: True, 16-bits training: False
Generating train split: 700000 examples [00:02, 282095.40 examples/s]
Generating validation split: 80665 examples [00:00, 268571.96 examples/s]
[INFO|configuration_utils.py:667] 2026-01-21 03:36:10,489 >> loading configuration file /workspace/hy-tmp/chatglm3-6b-32k/config.json
[INFO|configuration_utils.py:667] 2026-01-21 03:36:10,493 >> loading configuration file /workspace/hy-tmp/chatglm3-6b-32k/config.json
[INFO|configuration_utils.py:725] 2026-01-21 03:36:10,493 >> Model config ChatGLMConfig {
\”_name_or_path\”: \”/workspace/hy-tmp/chatglm3-6b-32k\”,
\”add_bias_linear\”: false,
\”add_qkv_bias\”: true,
\”apply_query_key_layer_scaling\”: true,
\”apply_residual_connection_post_layernorm\”: false,
\”architectures\”: [
\”ChatGLMModel\”
],
\”attention_dropout\”: 0.0,
\”attention_softmax_in_fp32\”: true,
\”auto_map\”: {
\”AutoConfig\”: \”configuration_chatglm.ChatGLMConfig\”,
\”AutoModel\”: \”modeling_chatglm.ChatGLMForConditionalGeneration\”,
\”AutoModelForCausalLM\”: \”modeling_chatglm.ChatGLMForConditionalGeneration\”,
\”AutoModelForSeq2SeqLM\”: \”modeling_chatglm.ChatGLMForConditionalGeneration\”,
\”AutoModelForSequenceClassification\”: \”modeling_chatglm.ChatGLMForSequenceClassification\”
},
\”bias_dropout_fusion\”: true,
\”classifier_dropout\”: null,
\”eos_token_id\”: 2,
\”ffn_hidden_size\”: 13696,
\”fp32_residual_connection\”: false,
\”hidden_dropout\”: 0.0,
\”hidden_size\”: 4096,
\”kv_channels\”: 128,
\”layernorm_epsilon\”: 1e-05,
\”model_type\”: \”chatglm\”,
\”multi_query_attention\”: true,
\”multi_query_group_num\”: 2,
\”num_attention_heads\”: 32,
\”num_layers\”: 28,
\”original_rope\”: true,
\”pad_token_id\”: 0,
\”padded_vocab_size\”: 65024,
\”post_layer_norm\”: true,
\”pre_seq_len\”: null,
\”prefix_projection\”: false,
\”quantization_bit\”: 0,
\”rmsnorm\”: true,
\”rope_ratio\”: 50,
\”seq_length\”: 32768,
\”tie_word_embeddings\”: false,
\”torch_dtype\”: \”float16\”,
\”transformers_version\”: \”4.30.2\”,
\”use_cache\”: true,
\”vocab_size\”: 65024
}

[INFO|tokenization_utils_base.py:1821] 2026-01-21 03:36:10,497 >> loading file tokenizer.model
[INFO|tokenization_utils_base.py:1821] 2026-01-21 03:36:10,497 >> loading file added_tokens.json
[INFO|tokenization_utils_base.py:1821] 2026-01-21 03:36:10,497 >> loading file special_tokens_map.json
[INFO|tokenization_utils_base.py:1821] 2026-01-21 03:36:10,497 >> loading file tokenizer_config.json
[INFO|modeling_utils.py:2575] 2026-01-21 03:36:10,735 >> loading weights file /workspace/hy-tmp/chatglm3-6b-32k/pytorch_model.bin.index.json
[INFO|configuration_utils.py:577] 2026-01-21 03:36:10,736 >> Generate config GenerationConfig {
\”_from_model_config\”: true,
\”eos_token_id\”: 2,
\”pad_token_id\”: 0,
\”transformers_version\”: \”4.30.2\”
}

Loading checkpoint shards: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [01:15<00:00, 10.81s/it]
[INFO|modeling_utils.py:3295] 2026-01-21 03:37:27,695 >> All model checkpoint weights were used when initializing ChatGLMForConditionalGeneration.

[WARNING|modeling_utils.py:3297] 2026-01-21 03:37:27,695 >> Some weights of ChatGLMForConditionalGeneration were not initialized from the model checkpoint at /workspace/hy-tmp/chatglm3-6b-32k and are newly initialized: [\’transformer.prefix_encoder.embedding.weight\’]
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
[INFO|modeling_utils.py:2927] 2026-01-21 03:37:27,697 >> Generation config file not found, using a generation config created from the model config.
Loading checkpoint shards: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [01:15<00:00, 10.83s/it]
[WARNING|modeling_utils.py:3297] 2026-01-21 03:37:27,858 >> Some weights of ChatGLMForConditionalGeneration were not initialized from the model checkpoint at /workspace/hy-tmp/chatglm3-6b-32k and are newly initialized: [\’transformer.prefix_encoder.embedding.weight\’]
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
Running tokenizer on train dataset (num_proc=10): 100%|███████████████████████████████████████████████████████████████████████████████████████| 700000/700000 [00:28<00:00, 24252.51 examples/s]
/usr/local/miniconda3/envs/py311/lib/python3.11/site-packages/torch/distributed/distributed_c10d.py:4876: UserWarning: barrier(): using the device under current context. You can specify `device_id` in `init_process_group` to mute this warning.
warnings.warn( # warn only once
[rank0]:[W121 03:37:57.127542164 ProcessGroupNCCL.cpp:5072] Guessing device ID based on global rank. This can cause a hang if rank to GPU mapping is heterogeneous. You can specify device_id in init_process_group()
input_ids [64790, 64792, 790, 30951, 517, 30910, 30939, 30996, 13, 13, 54761, 30954, 36680, 54805, 44436, 54585, 31750, 54602, 55321, 43408, 31514, 32638, 46860, 31123, 40920, 37492, 37079, 31123, 44436, 54585, 36050, 56270, 54530, 31123, 51084, 55662, 54530, 31123, 41339, 37079, 54706, 31123, 31714, 47911, 39581, 37874, 54549, 55333, 45458, 33423, 31642, 31731, 31123, 47911, 39581, 31155, 13, 13, 55437, 30954, 36474, 54591, 31123, 46860, 54585, 38822, 31211, 40920, 31937, 32623, 31123, 54573, 46958, 54589, 33102, 54969, 54962, 32420, 32445, 54659, 56735, 54977, 33464, 54642, 32445, 31123, 54627, 34956, 31201, 39513, 31201, 54544, 56672, 31201, 55994, 55491, 54542, 33745, 54609, 54659, 56735, 54977, 55002, 54642, 32445, 31155, 54627, 39833, 31201, 36240, 31201, 56007, 55343, 54643, 42298, 54609, 54659, 46180, 54675, 55761, 54605, 34484, 54659, 40920, 35505, 54680, 55158, 55273, 33974, 51239, 31123, 55630, 56561, 56884, 54659, 31937, 33503, 31123, 33573, 35700, 55553, 55433, 54659, 40920, 36428, 54698, 34533, 33342, 37815, 54698, 31201, 55251, 55350, 34533, 35050, 54746, 54578, 56207, 34343, 54554, 31123, 55073, 32155, 54619, 32718, 32064, 54746, 55119, 55639, 54659, 33666, 54987, 55092, 31155, 55756, 54591, 31155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
inputs [gMASK]sop [Round 1]

问: 人流两周后如何进补比较好?第一次人流,术后没什么不适,两周后吃了辣的,喝了冰的,并无不适感,现在该怎么改正这种情况会否对身体引发什么影响,该怎么改正。

答: 你好,人流后注意事项:术后注意营养,多排便高蛋白易消化的食物;忌食刺激性食物,如辣椒、生姜、生蒜、浓茶和咖啡等;忌食热性食物。如羊肉、牛肉、狗肉及海鲜等;始终保持外阴部清洁;术后一个月内严令禁止性生活,禁盆浴;注意休息,防止过度操劳;术后出血量低于平时月经量、破皮低于一周或下腹疼痛时,请及时与医生联系或随诊;定期复检。祝好。
label_ids [-100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 36474, 54591, 31123, 46860, 54585, 38822, 31211, 40920, 31937, 32623, 31123, 54573, 46958, 54589, 33102, 54969, 54962, 32420, 32445, 54659, 56735, 54977, 33464, 54642, 32445, 31123, 54627, 34956, 31201, 39513, 31201, 54544, 56672, 31201, 55994, 55491, 54542, 33745, 54609, 54659, 56735, 54977, 55002, 54642, 32445, 31155, 54627, 39833, 31201, 36240, 31201, 56007, 55343, 54643, 42298, 54609, 54659, 46180, 54675, 55761, 54605, 34484, 54659, 40920, 35505, 54680, 55158, 55273, 33974, 51239, 31123, 55630, 56561, 56884, 54659, 31937, 33503, 31123, 33573, 35700, 55553, 55433, 54659, 40920, 36428, 54698, 34533, 33342, 37815, 54698, 31201, 55251, 55350, 34533, 35050, 54746, 54578, 56207, 34343, 54554, 31123, 55073, 32155, 54619, 32718, 32064, 54746, 55119, 55639, 54659, 33666, 54987, 55092, 31155, 55756, 54591, 31155, 2, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100]
labels 你好,人流后注意事项:术后注意营养,多排便高蛋白易消化的食物;忌食刺激性食物,如辣椒、生姜、生蒜、浓茶和咖啡等;忌食热性食物。如羊肉、牛肉、狗肉及海鲜等;始终保持外阴部清洁;术后一个月内严令禁止性生活,禁盆浴;注意休息,防止过度操劳;术后出血量低于平时月经量、破皮低于一周或下腹疼痛时,请及时与医生联系或随诊;定期复检。祝好。
Running tokenizer on train dataset (num_proc=10): 3%|██▌ | 20000/700000 [00:01<00:30, 22285.24 examples/s][INFO|trainer.py:577] 2026-01-21 03:38:00,063 >> max_steps is given, it will override any value given in num_train_epochs
Running tokenizer on train dataset (num_proc=

赞(0)
未经允许不得转载:171主机测评 » ChatGLM3-6B P-Tuning v2 微调实战
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址