因为资源有限,但是想体验一下微调llm的实践效果,于是就使用internLM2的小模型进行了实验,1、2张卡就可以实验。本次没有使用任何模型量化,batchisze设置为6,并用了deepspeed zero2在两张 3090 24GB上满显存训练3轮训练了10分钟。

conda create -n xtuner0121 python=3.10 -y
conda install pytorch==2.7.1 torchvision==0.22.1 pytorch-cuda=12.1 -c pytorch -c nvidia -y
这里可以用pip下载,也可以使用清华源进行加速 -i https://pypi.tuna.tsinghua.edu.cn/simple 只要版本正确就行了
pip install transformers==4.43.0
这里要说明一下,我在qlora微调的时候使用的是这个版本,但是在后面推理的时候由于版本比较新,所以有一个bug,所以我在后面进行推理的时候使用的是版本4.39.3,读者可以选一个不新也不旧的版本
pip install streamlit==1.36.0
聊天对话的可视化
#创建一个目录,用来存放源代码 mkdir -p /home/finetune_qlora/ git clone -b v0.1.21 https://github.com/InternLM/XTuner /home/
pip install -e '.[deepspeed]'
你也可以将deepspeed改为all,所有相关软件都要下载
因为下载numpy会不知不觉使得numpy变为2.x以上的版本,所以我们降个级:
pip install numpy==1.23.5
xtuner version
找一个你认为合适的目录下载相应的模型,模型的网址是:internlm2_1_8b_chat 可以使用下面的命令进行下载:
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download --resume-download internlm/internlm2-chat-1_8b --local-dir (模型存放位置)
使用下面命令看一下原模型的效果: xtuner_streamlit_demo来源请看参考资料
streamlit run /home/finetune_qlora/xtuner_streamlit_demo.py
这个你就可以自己随便选了,只要你能想到的,但可以选一些比较有特点的,如果数据集太大或者逻辑复杂知识很多,那么这个1.5B模型可以都不太行,可能看不出效果。 比较快的方法是用chatgpt最强大的模型按照你的要求和格式直接生成大量的数据,我微调使用的数据就是用chatgpt生成的。 原本还想用deepseek api 一个一个生成,但是太慢了。 最后将你的数据保存在一个json文件里面,格式是:
[
{
"conversation": [
{
"system": "xxxx",
"input": "xxxxxxxx",
"output": "xxxxxxxxxxxxxxxxx"
},
{
"input": "xxxx",
"output": "xxxxxxxxxxxxxxxxxx"
},
{
"input": "xxxx",
"output": "xxxxxxxxxxxxxxxxxxx"
}
]
},
{
"conversation": [
{
"system": "xxxx",
"input": "xxxxxxxx",
"output": "xxxxxxxxxxxxxxxxx"
},
{
"input": "xxxx",
"output": "xxxxxxxxxxxxxxxxxx"
},
{
"input": "xxxx",
"output": "xxxxxxxxxxxxxxxxxxx"
}
]
}
]
xtuner list-cfg -p internlm2
拷贝到你的项目主目录, .是当前目录的意思
xtuner copy-cfg internlm2_chat_1_8b_qlora_alpaca_e3 .
参考后面相应的资料,我们做下面的修改:
pretrained_model_name_or_path = 'internlm/internlm2-chat-1_8b'
改成你自己模型的路径
alpaca_en_path = 'data/assistant.json'
量化一直报错,所以我就直接全部注释了
看参考资料的博客
xtuner train /home/finetune_qlora/internlm2_chat_1_8b_qlora_alpaca_e3_copy.py
如果想要使用deepspeed,就使用下面的命令:
xtuner train ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py --deepspeed deepspeed_zero2
如果你没有使用deepspeed,那你按照后面的博客操作,但是如果使用了deepspeed,我遇到了下面的问题。
In PyTorch 2.6, we changed the default value of the
weights_onlyargument intorch.loadfromFalsetoTrue. Re-runningtorch.loadwithweights_onlyset toFalsewill likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source. 我直接去了xtuner的源码在torch.load里面改成了state_dict = torch.load(pth_model, map_location='cpu', weights_only=False) 加了weights_only=False
(xtuner0121) root@qK6o3J:/home/finetune_qlora# xtuner convert pth_to_hf --fp32 ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py /home/finetune_qlora/work_dirs/internlm2_chat_1_8b_qlora_alpaca_e3_copy/iter_96.pth/mp_rank_00_model_states.pt ./hf [2025-06-07 16:02:42,793] [INFO] [real_accelerator.py:254:get_accelerator] Setting ds_accelerator to cuda (auto detect) [2025-06-07 16:02:48,283] [INFO] [real_accelerator.py:254:get_accelerator] Setting ds_accelerator to cuda (auto detect) Loading checkpoint shards: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 4.75it/s] Load State Dict: 0%| | 0/22 [00:00<?, ?it/s] Traceback (most recent call last): File "/home/xtuner0121/xtuner/tools/model_converters/pth_to_hf.py", line 139, in main() File "/home/xtuner0121/xtuner/tools/model_converters/pth_to_hf.py", line 115, in main set_module_tensor_to_device(model, name, 'cpu', param) File "/root/miniconda3/envs/xtuner0121/lib/python3.10/site-packages/accelerate/utils/modeling.py", line 260, in set_module_tensor_to_device raise ValueError(f"{module} does not have a parameter or a buffer named {tensor_name}.") ValueError: SupervisedFinetune( (data_preprocessor): BaseDataPreprocessor() (llm): PeftModelForCausalLM( (base_model): LoraModel( (model): InternLM2ForCausalLM( (model): InternLM2Model( (tok_embeddings): Embedding(92544, 2048, padding_idx=2) (layers): ModuleList( (0-23): 24 x InternLM2DecoderLayer( (attention): InternLM2Attention( (wqkv): lora.Linear( (base_layer): Linear(in_features=2048, out_features=4096, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=2048, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=4096, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) (wo): lora.Linear( (base_layer): Linear(in_features=2048, out_features=2048, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=2048, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=2048, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) (rotary_emb): InternLM2DynamicNTKScalingRotaryEmbedding() ) (feed_forward): InternLM2MLP( (w1): lora.Linear( (base_layer): Linear(in_features=2048, out_features=8192, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=2048, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=8192, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) (w3): lora.Linear( (base_layer): Linear(in_features=2048, out_features=8192, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=2048, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=8192, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) (w2): lora.Linear( (base_layer): Linear(in_features=8192, out_features=2048, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=8192, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=2048, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) (act_fn): SiLU() ) (attention_norm): InternLM2RMSNorm() (ffn_norm): InternLM2RMSNorm() ) ) (norm): InternLM2RMSNorm() ) (output): lora.Linear( (base_layer): Linear(in_features=2048, out_features=92544, bias=False) (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=2048, out_features=64, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=64, out_features=92544, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() (lora_magnitude_vector): ModuleDict() ) ) ) ) ) does not have a parameter or a buffer named module.
直接看最后一句话does not have a parameter or a buffer named module. 这是因为deepspeed会把原来的模型包裹在一个module里面,所以改成了:
add by nju-niu 这里加了一行,因为我使用了deepspeed的deepspeed_zero2来qlora微调,所以 它会在外面的模型上面再套一层module,这里我们只用取出参数进行转换,所以姑且这么写。 state_dict = state_dict['module'] for name, param in tqdm(state_dict.items(), desc='Load State Dict'): # print(f"name {name}\n" ) set_module_tensor_to_device(model, name, 'cpu', param)
最终使用下面命令进行转换:
xtuner convert pth_to_hf --fp32 ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py /home/finetune_qlora/work_dirs/internlm2_chat_1_8b_qlora_alpaca_e3_copy/iter_96.pth/mp_rank_00_model_states.pt ./hf
转化为huggingface格式后,我们将原来的模型和lora adaptor进行融合,形成最终的模型:
xtuner convert merge /home/ckpts/internlm2_1_8b_chat ./hf ./merged --max-shard-size 2GB
将xtuner_streamlit_demo.py里面的模型路径改成你合并后的路径,输入命令:
streamlit run ./xtuner_streamlit_demo.py
效果改进,但是如果更加深入,还是得全量微调并使用更大的模型。
一个博客:书生大模型实战营-L1-XTuner微调个人小助手认知 - JunyaoHu (胡钧耀) xtuner :Tutorial/tools/L1_XTuner_code/xtuner_streamlit_demo.py at camp4 · InternLM/Tutorial 这个py被用来可视化




