文章目录
XTuner 微调实践
1 创建环境
1.1 创建开发机
1.1.1 已有开发机升级GPU配置(推荐)
由于前面的任务已经创建过开发机,此时只需要将开发机GPU配置升级到30%(需要实战营助教解锁30%算力,可通过完成L1G2000任务解锁)
推荐该方式,因为通过前门的任务,已经安装过python3.10环境。
1.1.2 重新创建30%算力开发机
1.2 克隆数据并准备文件夹
cd ~
#git clone 本repo
git clone https://github.com/InternLM/Tutorial.git -b camp4
mkdir -p /root/finetune && cd /root/finetune
1.3 创建Python-3.10环境
conda create -n xtuner-env python=3.10 -y
conda activate xtuner-env
由于前面已经创建过相同的环境,因此这里直接激活,我的环境名是“envPython310”
1.4 安装XTuner
git clone https://github.com/InternLM/xtuner.git
cd /root/finetune/xtuner
pip install -e '.[all]'
pip install torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1 --index-url https://download.pytorch.org/whl/cu121
pip install transformers==4.39.0
完成后使用下面的命令验证是否安装成功
xtuner list-cfg
2 微调数据
2.1 创建目录用于存储微调数据
使用一下命令创建data文件夹,并将assistant_Tuner.jsonl 拷贝到里面
mkdir -p /root/finetune/data && cd /root/finetune/data
cp -r /root/Tutorial/data/assistant_Tuner.jsonl /root/finetune/data
2.2 修改脚本
2.2.1 创建change_script.py
# 创建 `change_script.py` 文件
touch /root/finetune/data/change_script.py
2.2.2 编辑change_script.py
import json
import argparse
from tqdm import tqdm
def process_line(line, old_text, new_text):
# 解析 JSON 行
data = json.loads(line)
# 递归函数来处理嵌套的字典和列表
def replace_text(obj):
if isinstance(obj, dict):
return {k: replace_text(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [replace_text(item) for item in obj]
elif isinstance(obj, str):
return obj.replace(old_text, new_text)
else:
return obj
# 处理整个 JSON 对象
processed_data = replace_text(data)
# 将处理后的对象转回 JSON 字符串
return json.dumps(processed_data, ensure_ascii=False)
def main(input_file, output_file, old_text, new_text):
with open(input_file, 'r', encoding='utf-8') as infile, \
open(output_file, 'w', encoding='utf-8') as outfile:
# 计算总行数用于进度条
total_lines = sum(1 for _ in infile)
infile.seek(0) # 重置文件指针到开头
# 使用 tqdm 创建进度条
for line in tqdm(infile, total=total_lines, desc="Processing"):
processed_line = process_line(line.strip(), old_text, new_text)
outfile.write(processed_line + '\n')
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
parser.add_argument("input_file", help="Input JSONL file to process")
parser.add_argument("output_file", help="Output file for processed JSONL")
parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
parser.add_argument("--new_text", default="机智流", help="Text to replace with")
args = parser.parse_args()
main(args.input_file, args.output_file, args.old_text, args.new_text)
2.2.3 修改与运行change_script.py
修改44行:
parser.add_argument(“–new_text”, default=“机智流”, help=“Text to replace with”)
中的“机智流”为自己的昵称,执行以下命令运行脚本
# usage:python change_script.py {input_file.jsonl} {output_file.jsonl}
cd ~/finetune/data
python change_script.py ./assistant_Tuner.jsonl ./assistant_Tuner_change.jsonl
生成一个新的jsonl文件,打开查看,其中称呼已经更改
3 训练
3.1 复制模型
mkdir /root/finetune/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/finetune/models/internlm2_5-7b-chat
3.2 修改config
获取官方写好的 config
# cd {path/to/finetune}
cd /root/finetune
mkdir ./config
cd config
xtuner copy-cfg internlm2_5_chat_7b_qlora_alpaca_e3 ./
打开文件
修改以下几行数据,将标记“-”的行改为标记“+”的行
#######################################################################
# PART 1 Settings #
#######################################################################
- pretrained_model_name_or_path = 'internlm/internlm2_5-7b-chat'
+ pretrained_model_name_or_path = '/root/finetune/models/internlm2_5-7b-chat'
- alpaca_en_path = 'tatsu-lab/alpaca'
+ alpaca_en_path = '/root/finetune/data/assistant_Tuner_change.jsonl'
evaluation_inputs = [
- '请给我介绍五个上海的景点', 'Please tell me five scenic spots in Shanghai'
+ '请介绍一下你自己', 'Please introduce yourself'
]
#######################################################################
# PART 3 Dataset & Dataloader #
#######################################################################
alpaca_en = dict(
type=process_hf_dataset,
- dataset=dict(type=load_dataset, path=alpaca_en_path),
+ dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
tokenizer=tokenizer,
max_length=max_length,
- dataset_map_fn=alpaca_map_fn,
+ dataset_map_fn=None,
template_map_fn=dict(
type=template_map_fn_factory, template=prompt_template),
remove_unused_columns=True,
shuffle_before_pack=True,
pack_to_max_length=pack_to_max_length,
use_varlen_attn=use_varlen_attn)
还可以对其他参数进行微调,常见参数如下
3.3 启动
执行以下命令即可启动微调,注意:第二行中的环境名,这里是我创建的环境名,需要改为自己真实的环境名,下同
cd /root/finetune
conda activate envPython310
xtuner train ./config/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py --deepspeed deepspeed_zero2 --work-dir ./work_dirs/assistTuner
3.4 权重转换
cd /root/finetune/work_dirs/assistTuner
conda activate envPython310
# 先获取最后保存的一个pth文件
pth_file=`ls -t /root/finetune/work_dirs/assistTuner/*.pth | head -n 1 | sed 's/:$//'`
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert pth_to_hf ./internlm2_5_chat_7b_qlora_alpaca_e3_copy.py ${pth_file} ./hf
完成后截图图下
生成的目录结构
3.5 模型合并
cd /root/finetune/work_dirs/assistTuner
conda activate envPython310
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert merge /root/finetune/models/internlm2_5-7b-chat ./hf ./merged --max-shard-size 2GB
完成后截图
3.6 对话
在~/Tutorial/tools/L1_XTuner_code路径下打开xtuner_streamlit_demo.py文件
修改33行
- model_name_or_path = "Shanghai_AI_Laboratory/internlm2_5-7b-chat"
+ model_name_or_path = "/root/finetune/work_dirs/assistTuner/merged"
运行以下命令
conda activate envPython310
streamlit run /root/Tutorial/tools/L1_XTuner_code/xtuner_streamlit_demo.py
等到运行后,即可在浏览器打开地址http://localhost:8502/进行对话