(笔记+作业)书生大模型实战营春节卷王班---L1G5000 XTuner 微调个人小助手认知
(笔记+作业)书生大模型实战营春节卷王班---L1G5000 XTuner 微调个人小助手认知
学员闯关手册:https://aicarrier.feishu.cn/wiki/QtJnweAW1iFl8LkoMKGcsUS9nld
课程视频:https://www.bilibili.com/video/BV13U1VYmEUr/
课程文档:https://github.com/InternLM/Tutorial/tree/camp4/docs/L0/Python
关卡作业:https://github.com/InternLM/Tutorial/blob/camp4/docs/L0/Python/task.md
开发机平台:https://studio.intern-ai.org.cn/
开发机平台介绍:https://aicarrier.feishu.cn/wiki/GQ1Qwxb3UiQuewk8BVLcuyiEnHe
书生浦语官网:https://internlm.intern-ai.org.cn/
github网站:https://github.com/internLM/
XTuner 文档链接:https://xtuner.readthedocs.io/zh-cn/latest/



基础任务:完成个人小助手微调
#环境坏了删除环境和文件
conda deactivate
conda env remove --name xtuner-env
# 删除目录
rm -rf /root/.conda/envs/xtuner-env
#并删除文件夹Tutorial、finetune、InternLM
conda env list
#1、环境配置与数据准备
#使用 conda 先构建一个 Python-3.10 的虚拟环境
cd ~
#git clone 本repo,先在我的云盘里删去Tutorial文件夹
git clone https://github.com/InternLM/Tutorial.git -b camp4 #文件夹多了Tutorial
mkdir -p /root/finetune && cd /root/finetune #文件夹多了finetune
conda create -n xtuner-env python=3.10 -y
conda activate xtuner-env
# 安装 XTuner
cd /root/Tutorial/docs/L1/XTuner
pip install -r requirements.txt
#如果报错,换成pip install --trusted-host mirrors.aliyun.com -e '.[deepspeed]' -i https://mirrors.aliyun.com/pypi/simple/
#验证是否安装成功
xtuner list-cfg
#2、修改提供的数据
#2.1、创建一个新的文件夹用于存储微调数据
mkdir -p /root/finetune/data && cd /root/finetune/data #多一个finetune文件夹
cp -r /root/Tutorial/data/assistant_Tuner.jsonl /root/finetune/data
# 2.2、创建 `change_script.py` 文件
touch /root/finetune/data/change_script.py
#2.3、编辑change_script.py
# 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 #assistant_Tuner_change.jsonl 是修改后符合 XTuner 格式的训练数据。
#查看数据cat assistant_Tuner_change.jsonl | head -n 3
#3、复制模型和修改config
#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
# cd {path/to/finetune}
cd /root/finetune
mkdir ./config
cd config
xtuner copy-cfg internlm2_5_chat_7b_qlora_alpaca_e3 ./
#修改 Config,或者本教程已经将改好的 config 放在了 ~/Tutorial/configs/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py 同学们可以直接使用(前置步骤路径一致的情况下)
#4、训练
#4.1、启动微调
cd /root/finetune
conda activate xtuner-env
xtuner train ./config/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py --deepspeed deepspeed_zero2 --work-dir ./work_dirs/assistTuner
#4.2、权重转换
cd /root/finetune/work_dirs/assistTuner
conda activate xtuner-env
# 先获取最后保存的一个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 命令用于进行模型格式转换。该命令需要三个参数:CONFIG 表示微调的配置文件, PATH_TO_PTH_MODEL 表示微调的模型权重文件路径,即要转换的模型权重, SAVE_PATH_TO_HF_MODEL 表示转换后的 HuggingFace 格式文件的保存路径。
xtuner convert pth_to_hf ./internlm2_5_chat_7b_qlora_alpaca_e3_copy.py ${pth_file} ./hf
#此时,hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”,可以简单理解:LoRA 模型文件 = Adapter
#4.3、模型合并
#xtuner convert merge命令用于合并模型。该命令需要三个参数:LLM 表示原模型路径,ADAPTER 表示 Adapter 层的路径, SAVE_PATH 表示合并后的模型最终的保存路径。
cd /root/finetune/work_dirs/assistTuner
conda activate xtuner-env
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
#5、模型 WebUI 对话
#5.1、修改xtuner_streamlit_demo.py
cd ~/Tutorial/tools/L1_XTuner_code
# 直接修改脚本文件xtuner_streamlit_demo.py第18行
- model_name_or_path = "Shanghai_AI_Laboratory/internlm2_5-7b-chat"
+ model_name_or_path = "/root/finetune/work_dirs/assistTuner/merged"
#进行ssh端口映射
#ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p 48021
#5.2、直接启动应用
conda activate xtuner-env
pip install streamlit==1.31.0
streamlit run /root/Tutorial/tools/L1_XTuner_code/xtuner_streamlit_demo.py
#浏览器http://127.0.0.1:8501
#2.3、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)
#3.2、修改config
#######################################################################
# 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.2、修改后的config
# Copyright (c) OpenMMLab. All rights reserved.
import torch
from datasets import load_dataset
from mmengine.dataset import DefaultSampler
from mmengine.hooks import (CheckpointHook, DistSamplerSeedHook, IterTimerHook,
LoggerHook, ParamSchedulerHook)
from mmengine.optim import AmpOptimWrapper, CosineAnnealingLR, LinearLR
from peft import LoraConfig
from torch.optim import AdamW
from transformers import (AutoModelForCausalLM, AutoTokenizer,
BitsAndBytesConfig)
from xtuner.dataset import process_hf_dataset
from xtuner.dataset.collate_fns import default_collate_fn
from xtuner.dataset.map_fns import alpaca_map_fn, template_map_fn_factory
from xtuner.engine.hooks import (DatasetInfoHook, EvaluateChatHook,
VarlenAttnArgsToMessageHubHook)
from xtuner.engine.runner import TrainLoop
from xtuner.model import SupervisedFinetune
from xtuner.parallel.sequence import SequenceParallelSampler
from xtuner.utils import PROMPT_TEMPLATE, SYSTEM_TEMPLATE
#######################################################################
# PART 1 Settings #
#######################################################################
# Model
pretrained_model_name_or_path = '/root/finetune/models/internlm2_5-7b-chat'
use_varlen_attn = False
# Data
alpaca_en_path = '/root/finetune/data/assistant_Tuner_change.jsonl'
prompt_template = PROMPT_TEMPLATE.internlm2_chat
max_length = 2048
pack_to_max_length = True
# parallel
sequence_parallel_size = 1
# Scheduler & Optimizer
batch_size = 1 # per_device
accumulative_counts = 1
accumulative_counts *= sequence_parallel_size
dataloader_num_workers = 0
max_epochs = 3
optim_type = AdamW
lr = 2e-4
betas = (0.9, 0.999)
weight_decay = 0
max_norm = 1 # grad clip
warmup_ratio = 0.03
# Save
save_steps = 500
save_total_limit = 2 # Maximum checkpoints to keep (-1 means unlimited)
# Evaluate the generation performance during the training
evaluation_freq = 500
SYSTEM = SYSTEM_TEMPLATE.alpaca
evaluation_inputs = [
'请介绍一下你自己', 'Please introduce yourself'
]
#######################################################################
# PART 2 Model & Tokenizer #
#######################################################################
tokenizer = dict(
type=AutoTokenizer.from_pretrained,
pretrained_model_name_or_path=pretrained_model_name_or_path,
trust_remote_code=True,
padding_side='right')
model = dict(
type=SupervisedFinetune,
use_varlen_attn=use_varlen_attn,
llm=dict(
type=AutoModelForCausalLM.from_pretrained,
pretrained_model_name_or_path=pretrained_model_name_or_path,
trust_remote_code=True,
torch_dtype=torch.float16,
quantization_config=dict(
type=BitsAndBytesConfig,
load_in_4bit=True,
load_in_8bit=False,
llm_int8_threshold=6.0,
llm_int8_has_fp16_weight=False,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type='nf4')),
lora=dict(
type=LoraConfig,
r=64,
lora_alpha=16,
lora_dropout=0.1,
bias='none',
task_type='CAUSAL_LM'))
#######################################################################
# PART 3 Dataset & Dataloader #
#######################################################################
alpaca_en = dict(
type=process_hf_dataset,
dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
tokenizer=tokenizer,
max_length=max_length,
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)
sampler = SequenceParallelSampler \
if sequence_parallel_size > 1 else DefaultSampler
train_dataloader = dict(
batch_size=batch_size,
num_workers=dataloader_num_workers,
dataset=alpaca_en,
sampler=dict(type=sampler, shuffle=True),
collate_fn=dict(type=default_collate_fn, use_varlen_attn=use_varlen_attn))
#######################################################################
# PART 4 Scheduler & Optimizer #
#######################################################################
# optimizer
optim_wrapper = dict(
type=AmpOptimWrapper,
optimizer=dict(
type=optim_type, lr=lr, betas=betas, weight_decay=weight_decay),
clip_grad=dict(max_norm=max_norm, error_if_nonfinite=False),
accumulative_counts=accumulative_counts,
loss_scale='dynamic',
dtype='float16')
# learning policy
# More information: https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/param_scheduler.md # noqa: E501
param_scheduler = [
dict(
type=LinearLR,
start_factor=1e-5,
by_epoch=True,
begin=0,
end=warmup_ratio * max_epochs,
convert_to_iter_based=True),
dict(
type=CosineAnnealingLR,
eta_min=0.0,
by_epoch=True,
begin=warmup_ratio * max_epochs,
end=max_epochs,
convert_to_iter_based=True)
]
# train, val, test setting
train_cfg = dict(type=TrainLoop, max_epochs=max_epochs)
#######################################################################
# PART 5 Runtime #
#######################################################################
# Log the dialogue periodically during the training process, optional
custom_hooks = [
dict(type=DatasetInfoHook, tokenizer=tokenizer),
dict(
type=EvaluateChatHook,
tokenizer=tokenizer,
every_n_iters=evaluation_freq,
evaluation_inputs=evaluation_inputs,
system=SYSTEM,
prompt_template=prompt_template)
]
if use_varlen_attn:
custom_hooks += [dict(type=VarlenAttnArgsToMessageHubHook)]
# configure default hooks
default_hooks = dict(
# record the time of every iteration.
timer=dict(type=IterTimerHook),
# print log every 10 iterations.
logger=dict(type=LoggerHook, log_metric_by_epoch=False, interval=10),
# enable the parameter scheduler.
param_scheduler=dict(type=ParamSchedulerHook),
# save checkpoint per `save_steps`.
checkpoint=dict(
type=CheckpointHook,
by_epoch=False,
interval=save_steps,
max_keep_ckpts=save_total_limit),
# set sampler seed in distributed evrionment.
sampler_seed=dict(type=DistSamplerSeedHook),
)
# configure environment
env_cfg = dict(
# whether to enable cudnn benchmark
cudnn_benchmark=False,
# set multi process parameters
mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
# set distributed parameters
dist_cfg=dict(backend='nccl'),
)
# set visualizer
visualizer = None
# set log level
log_level = 'INFO'
# load from which checkpoint
load_from = None
# whether to resume training from the loaded checkpoint
resume = False
# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=None, deterministic=False)
# set log processor
log_processor = dict(by_epoch=False)
4.3、模型合并后文件目录结构




#5.1、修改xtuner_streamlit_demo.py
"""This script refers to the dialogue example of streamlit, the interactive
generation code of chatglm2 and transformers.
We mainly modified part of the code logic to adapt to the
generation of our model.
Please refer to these links below for more information:
1. streamlit chat example:
https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps
2. chatglm2:
https://github.com/THUDM/ChatGLM2-6B
3. transformers:
https://github.com/huggingface/transformers
Please run with the command `streamlit run path/to/web_demo.py
--server.address=0.0.0.0 --server.port 7860`.
Using `python path/to/web_demo.py` may cause unknown problems.
"""
# isort: skip_file
import copy
import warnings
from dataclasses import asdict, dataclass
from typing import Callable, List, Optional
import streamlit as st
import torch
from torch import nn
from transformers.generation.utils import (LogitsProcessorList,
StoppingCriteriaList)
from transformers.utils import logging
from transformers import AutoTokenizer, AutoModelForCausalLM # isort: skip
logger = logging.get_logger(__name__)
model_name_or_path="/root/finetune/work_dirs/assistTuner/merged"
@dataclass
class GenerationConfig:
# this config is used for chat to provide more diversity
max_length: int = 32768
top_p: float = 0.8
temperature: float = 0.8
do_sample: bool = True
repetition_penalty: float = 1.005
@torch.inference_mode()
def generate_interactive(
model,
tokenizer,
prompt,
generation_config: Optional[GenerationConfig] = None,
logits_processor: Optional[LogitsProcessorList] = None,
stopping_criteria: Optional[StoppingCriteriaList] = None,
prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor],
List[int]]] = None,
additional_eos_token_id: Optional[int] = None,
**kwargs,
):
inputs = tokenizer([prompt], padding=True, return_tensors='pt')
input_length = len(inputs['input_ids'][0])
for k, v in inputs.items():
inputs[k] = v.cuda()
input_ids = inputs['input_ids']
_, input_ids_seq_length = input_ids.shape[0], input_ids.shape[-1]
if generation_config is None:
generation_config = model.generation_config
generation_config = copy.deepcopy(generation_config)
model_kwargs = generation_config.update(**kwargs)
bos_token_id, eos_token_id = ( # noqa: F841 # pylint: disable=W0612
generation_config.bos_token_id,
generation_config.eos_token_id,
)
if isinstance(eos_token_id, int):
eos_token_id = [eos_token_id]
if additional_eos_token_id is not None:
eos_token_id.append(additional_eos_token_id)
has_default_max_length = kwargs.get(
'max_length') is None and generation_config.max_length is not None
if has_default_max_length and generation_config.max_new_tokens is None:
warnings.warn(
f"Using 'max_length''s default \
({repr(generation_config.max_length)}) \
to control the generation length. "
'This behaviour is deprecated and will be removed from the \
config in v5 of Transformers -- we'
' recommend using `max_new_tokens` to control the maximum \
length of the generation.',
UserWarning,
)
elif generation_config.max_new_tokens is not None:
generation_config.max_length = generation_config.max_new_tokens + \
input_ids_seq_length
if not has_default_max_length:
logger.warn( # pylint: disable=W4902
f"Both 'max_new_tokens' (={generation_config.max_new_tokens}) "
f"and 'max_length'(={generation_config.max_length}) seem to "
"have been set. 'max_new_tokens' will take precedence. "
'Please refer to the documentation for more information. '
'(https://huggingface.co/docs/transformers/main/'
'en/main_classes/text_generation)',
UserWarning,
)
if input_ids_seq_length >= generation_config.max_length:
input_ids_string = 'input_ids'
logger.warning(
f'Input length of {input_ids_string} is {input_ids_seq_length}, '
f"but 'max_length' is set to {generation_config.max_length}. "
'This can lead to unexpected behavior. You should consider'
" increasing 'max_new_tokens'.")
# 2. Set generation parameters if not already defined
logits_processor = logits_processor if logits_processor is not None \
else LogitsProcessorList()
stopping_criteria = stopping_criteria if stopping_criteria is not None \
else StoppingCriteriaList()
logits_processor = model._get_logits_processor(
generation_config=generation_config,
input_ids_seq_length=input_ids_seq_length,
encoder_input_ids=input_ids,
prefix_allowed_tokens_fn=prefix_allowed_tokens_fn,
logits_processor=logits_processor,
)
stopping_criteria = model._get_stopping_criteria(
generation_config=generation_config,
stopping_criteria=stopping_criteria)
logits_warper = model._get_logits_warper(generation_config)
unfinished_sequences = input_ids.new(input_ids.shape[0]).fill_(1)
scores = None
while True:
model_inputs = model.prepare_inputs_for_generation(
input_ids, **model_kwargs)
# forward pass to get next token
outputs = model(
**model_inputs,
return_dict=True,
output_attentions=False,
output_hidden_states=False,
)
next_token_logits = outputs.logits[:, -1, :]
# pre-process distribution
next_token_scores = logits_processor(input_ids, next_token_logits)
next_token_scores = logits_warper(input_ids, next_token_scores)
# sample
probs = nn.functional.softmax(next_token_scores, dim=-1)
if generation_config.do_sample:
next_tokens = torch.multinomial(probs, num_samples=1).squeeze(1)
else:
next_tokens = torch.argmax(probs, dim=-1)
# update generated ids, model inputs, and length for next step
input_ids = torch.cat([input_ids, next_tokens[:, None]], dim=-1)
model_kwargs = model._update_model_kwargs_for_generation(
outputs, model_kwargs, is_encoder_decoder=False)
unfinished_sequences = unfinished_sequences.mul(
(min(next_tokens != i for i in eos_token_id)).long())
output_token_ids = input_ids[0].cpu().tolist()
output_token_ids = output_token_ids[input_length:]
for each_eos_token_id in eos_token_id:
if output_token_ids[-1] == each_eos_token_id:
output_token_ids = output_token_ids[:-1]
response = tokenizer.decode(output_token_ids)
yield response
# stop when each sentence is finished
# or if we exceed the maximum length
if unfinished_sequences.max() == 0 or stopping_criteria(
input_ids, scores):
break
def on_btn_click():
del st.session_state.messages
@st.cache_resource
def load_model():
model = (AutoModelForCausalLM.from_pretrained(
model_name_or_path,
trust_remote_code=True).to(torch.bfloat16).cuda())
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,
trust_remote_code=True)
return model, tokenizer
def prepare_generation_config():
with st.sidebar:
max_length = st.slider('Max Length',
min_value=8,
max_value=32768,
value=32768)
top_p = st.slider('Top P', 0.0, 1.0, 0.8, step=0.01)
temperature = st.slider('Temperature', 0.0, 1.0, 0.7, step=0.01)
st.button('Clear Chat History', on_click=on_btn_click)
generation_config = GenerationConfig(max_length=max_length,
top_p=top_p,
temperature=temperature)
return generation_config
user_prompt = '<|im_start|>user\n{user}<|im_end|>\n'
robot_prompt = '<|im_start|>assistant\n{robot}<|im_end|>\n'
cur_query_prompt = '<|im_start|>user\n{user}<|im_end|>\n\
<|im_start|>assistant\n'
def combine_history(prompt):
messages = st.session_state.messages
meta_instruction = ('You are a helpful, honest, '
'and harmless AI assistant.')
total_prompt = f'<s><|im_start|>system\n{meta_instruction}<|im_end|>\n'
for message in messages:
cur_content = message['content']
if message['role'] == 'user':
cur_prompt = user_prompt.format(user=cur_content)
elif message['role'] == 'robot':
cur_prompt = robot_prompt.format(robot=cur_content)
else:
raise RuntimeError
total_prompt += cur_prompt
total_prompt = total_prompt + cur_query_prompt.format(user=prompt)
return total_prompt
def main():
st.title('internlm2_5-7b-chat-assistant')
# torch.cuda.empty_cache()
print('load model begin.')
model, tokenizer = load_model()
print('load model end.')
generation_config = prepare_generation_config()
# Initialize chat history
if 'messages' not in st.session_state:
st.session_state.messages = []
# Display chat messages from history on app rerun
for message in st.session_state.messages:
with st.chat_message(message['role'], avatar=message.get('avatar')):
st.markdown(message['content'])
# Accept user input
if prompt := st.chat_input('What is up?'):
# Display user message in chat message container
with st.chat_message('user', avatar='user'):
st.markdown(prompt)
real_prompt = combine_history(prompt)
# Add user message to chat history
st.session_state.messages.append({
'role': 'user',
'content': prompt,
'avatar': 'user'
})
with st.chat_message('robot', avatar='assistant'):
message_placeholder = st.empty()
for cur_response in generate_interactive(
model=model,
tokenizer=tokenizer,
prompt=real_prompt,
additional_eos_token_id=92542,
device='cuda:0',
**asdict(generation_config),
):
# Display robot response in chat message container
message_placeholder.markdown(cur_response + '▌')
message_placeholder.markdown(cur_response)
# Add robot response to chat history
st.session_state.messages.append({
'role': 'robot',
'content': cur_response, # pylint: disable=undefined-loop-variable
'avatar': 'assistant',
})
torch.cuda.empty_cache()
if __name__ == '__main__':
main()
实验效果
环境准备
Xtuner安装成功
数据集准备
把已有的个人认知训练数据集中的名字替换为自己的名字。



模型准备

配置文件准备


训练报错
训练报错了
这个错误提示表明,你在运行命令时,程序无法从 torch.distributed.elastic.agent.server.api 中导入 log 函数,可能是因为 PyTorch 或 xtuner 版本之间的不兼容导致的。具体的错误信息是:
WARNING - WARNING: command error: 'cannot import name 'log' from 'torch.distributed.elastic.agent.server.api' (/root/.conda/envs/xtuner-env/lib/python3.10/site-packages/torch/distributed/elastic/agent/server/api.py)'!
可能的解决方法:
-
更新 PyTorch 版本:
这个错误可能是由于 PyTorch 版本过老,无法找到log函数。尝试更新到最新稳定版本的 PyTorch:pip install --upgrade torch更新完成后,再次尝试运行命令。
-
检查
xtuner与 PyTorch 的兼容性:
确保你正在使用的xtuner版本与安装的 PyTorch 版本是兼容的。有时候,不同版本的库会有 breaking changes,导致 API 不兼容。可以查看xtuner和 PyTorch 的官方文档,确保它们的版本匹配。 -
修改代码(如果可以):
如果你可以编辑xtuner的代码,可以检查导致问题的import语句,通常是类似下面的:from torch.distributed.elastic.agent.server.api import log如果
log函数已经不再提供,可能需要替换为其他的日志记录方式,比如 Python 内置的logging模块,或者其他的日志工具。 -
使用正确的环境:
如果环境配置有问题,可能会导致版本不匹配的错误。你可以尝试创建一个新的虚拟环境,安装与xtuner和 PyTorch 兼容的版本:conda create -n new_xtuner_env python=3.10 conda activate new_xtuner_env pip install torch==<指定版本> xtuner -
查阅
xtuner文档:
由于xtuner是一个特定的工具,查看其文档或 GitHub 上的问题讨论可能会提供更多的信息。有可能是xtuner需要更新或修复,或者在配置和使用时有特定的要求。
通过这些步骤,你应该能够解决或绕过这个错误。如果你有对代码进行修改的权限,可以尝试找到更合适的日志记录方式,或者直接解决兼容性问题。
核对操作文档,发现我多加了一句

重新安装包,希望不要从头再来一遍,


好像开始正常训练了



30%的算力,1.5个小时训练完毕
权重转换与合并


模型webUI对话

SSH端口映射
端口映射后打不开网页
采用以下ssh端口映射
配置SSH密钥进行SSH远程连接
将本地生成的SSH密钥复制粘贴到远程添加SSH公钥,建立SSH远程连接,优点:完成SSH Key创建以后,重启终端进行远程连接,就会跳过密码输入这一步了。
电脑power shell–》ssh-keygen -t rsa(# 生成RSA密钥对)—》cat ~/.ssh/id_rsa.pub(# 查询生成的公钥)
开发机–》SSH Key配置—》添加SSH Key公钥

运行python文件后,点击ports的网址


自我认知模型上传并部署到 HuggingFace/Modelscope/魔乐平台
HF的spaces创建项目
浏览器https://huggingface.co/spaces
–》Create new Space
–》在创建页面中,输入项目名为/internlm2_5-7b-chat-assistant,并选择 Streamlit应用进行创建,https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
–》创建成功后会自动跳转到一个默认的HTML页面,编辑好app.py,
–》使用huggingface-cli login命令进行登录,登录过程中需要输入用户的Access Tokens,获取时,需要先验证email,完成验证后,点击create new token,创建一个类型为“Write”的token,并请复制好token后要存储在合适的地方
–》创建好项目后,回到我们的CodeSpace,接着clone项目。
在弹出的页面中,点击【create app.py】,直接编辑app.py,然后提交
#app.py就是5.1、修改xtuner_streamlit_demo.py
#修改模型路径model_name_or_path = "haidizym/internlm2_5-7b-chat-assistant-zymassistant"
git编辑更新项目
未能完成项目:本地 git bash
#1.准备环境
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
git lfs install
pip install huggingface_hub
git config --global credential.helper store
huggingface-cli login #命令进行登录,这时需要输入刚刚的token
#2.上传大模型文件到https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
huggingface-cli repo internlm2_5-7b-chat-assistant-zymassistant
cd /d
git clone https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
#把开发机上已经训练好的模型/root/finetune/work_dirs/assistTuner/merged下载到本地,存到刚才克隆下的来的文件夹internlm2_5-7b-chat-assistant-zymassistant里,/root/Tutorial/docs/L1/XTuner/requirements.txt也下载到本地,
cd internlm2_5-7b-chat-assistant-zymassistant
#添提推
git add .
git commit -m "add:internlm2_5-7b-chat-assistant-zymassistant"
git push
#3.部署Streamlit应用到https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
#在https://huggingface.co/spaces新建好Streamlit应用https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant,并把xtuner_streamlit_demo.py内容粘贴到app.py中,修改模型路径model_name_or_path="/root/finetune/work_dirs/assistTuner/merged"为model_name_or_path = "haidizym/internlm2_5-7b-chat-assistant-zymassistant"
#使用镜像站点模型model_name_or_path = "https://hf-mirror.com/haidizym/internlm2_5-7b-chat-assistant-zymassistant"
#在https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant新建好requirements.txt,
#以上操作在https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant完成后,不再需要以下的操作
#cd d
#git clone https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
#添提推
#git add .
#git commit -m "update: colearn page"
#git push
#需要输入HF的access token
成功项目:开发机
在开发机上使用huggingface-cli login连接上HF后(环境准备),创建上传大模型文件https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
(使用镜像export HF_ENDPOINT=https://hf-mirror.com),部署Streamlit应用到https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
#1.准备环境
conda activate xtuner-env
apt install sudo
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs
pip install huggingface_hub
git config --global credential.helper store
huggingface-cli login #命令进行登录,这时需要输入刚刚的token
#2.上传大模型文件到https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
huggingface-cli repo create internlm2_5-7b-chat-assistant-zymassistant
#加这句好像可以加速export HF_ENDPOINT=https://hf-mirror.com,又或者使用WATT给hugging face加速,不会弄WATT
export HF_ENDPOINT=https://hf-mirror.com
cd /root/finetune/work_dirs/assistTuner
#git clone https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
git clone https://hf-mirror.com/haidizym/internlm2_5-7b-chat-assistant-zymassistant
#我想把/root/finetune/work_dirs/assistTuner/merged这个文件夹里的全部文件上传到https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant这里,这里克隆仓库以后,应该添一行什么代码,使得/root/finetune/work_dirs/assistTuner/merged这个文件夹里的全部文件在仓库里可以直接上传?
cd internlm2_5-7b-chat-assistant-zymassistant
cp -r /root/finetune/work_dirs/assistTuner/merged/* .
#添提推
git add .
git commit -m "add:internlm2_5-7b-chat-assistant-zymassistant"
git push
#3.部署Streamlit应用到https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
#3.1 HF创建Streamlit应用https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant
#3.2 app.py编辑:在https://huggingface.co/spaces新建好Streamlit应用https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant,并把xtuner_streamlit_demo.py内容粘贴到app.py中,修改模型路径model_name_or_path="/root/finetune/work_dirs/assistTuner/merged"为model_name_or_path = "haidizym/internlm2_5-7b-chat-assistant-zymassistant"
#3.3 requirements.txt编辑:在https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant新建好requirements.txt,
#以上操作在https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant完成后,不再需要其他git操作
准备环境
连接HF,huggingface-cli login
貌似克隆模型仓库要花很久,这里留下两个时间节点
等了20分钟没反应,在克隆前加了这句export HF_ENDPOINT=https://hf-mirror.com,重新克隆,很快
git clone https://hf-mirror.com/haidizym/internlm2_5-7b-chat-assistant-zymassistant

添提推模型文件
14G模型文件约20分钟上传完

镜像上模型好了以后,一会后HF上也有了模型文件,https://huggingface.co/haidizym/internlm2_5-7b-chat-assistant-zymassistant
app.py文件编辑
创建环境配置requirements.txt文件
直接访问应用https://huggingface.co/spaces/haidizym/internlm2_5-7b-chat-assistant,
运行了约2个小时还是这个界面,估计没问题了,可能是HF提供的免费算力不够运行出来
附录:
环境配置requirements.txt
#cd /root/Tutorial/docs/L1/XTuner
#pip install -r requirements.txt
accelerate==0.27.0
addict==2.4.0
aiohttp==3.9.3
aiosignal==1.3.1
aliyun-python-sdk-core==2.14.0
aliyun-python-sdk-kms==2.16.2
altair==5.2.0
annotated-types==0.6.0
anyio==4.2.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
arxiv==2.1.0
asttokens==2.4.1
async-lru==2.0.4
async-timeout==4.0.3
attrs==23.2.0
Babel==2.14.0
beautifulsoup4==4.12.3
bitsandbytes==0.42.0
bleach==6.1.0
blinker==1.7.0
cachetools==5.3.2
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
comm==0.2.1
contourpy==1.2.0
crcmod==1.7
cryptography==42.0.2
cycler==0.12.1
datasets==2.17.0
debugpy==1.8.1
decorator==5.1.1
deepspeed==0.13.1
defusedxml==0.7.1
dill==0.3.8
distro==1.9.0
einops==0.8.0
einx==0.3.0
et-xmlfile==1.1.0
exceptiongroup==1.2.0
executing==2.0.1
fastapi==0.112.0
fastjsonschema==2.19.1
feedparser==6.0.10
filelock==3.14.0
fonttools==4.48.1
fqdn==1.5.1
frozendict==2.4.4
frozenlist==1.4.1
fsspec==2023.10.0
func-timeout==4.3.5
gast==0.5.4
gitdb==4.0.11
GitPython==3.1.41
google-search-results==2.4.2
griffe==0.40.1
h11==0.14.0
hjson==3.1.0
httpcore==1.0.3
httpx==0.26.0
huggingface-hub==0.24.2
idna==3.6
imageio==2.34.2
importlib-metadata==7.0.1
ipykernel==6.29.2
ipython==8.21.0
ipywidgets==8.1.2
isoduration==20.11.0
jedi==0.19.1
Jinja2==3.1.3
jmespath==0.10.0
json5==0.9.14
jsonpointer==2.4
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
kiwisolver==1.4.5
lagent==0.2.1
lazy_loader==0.4
llvmlite==0.43.0
lxml==5.1.0
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib==3.8.2
matplotlib-inline==0.1.6
mdurl==0.1.2
mistune==3.0.2
mmengine==0.10.3
modelscope==1.12.0
mpi4py_mpich==3.1.5
mpmath==1.3.0
multidict==6.0.5
multiprocess==0.70.16
nbclient==0.9.0
nbconvert==7.16.0
nbformat==5.9.2
nest-asyncio==1.6.0
networkx==3.2.1
ninja==1.11.1.1
notebook==7.0.8
notebook_shim==0.2.3
numba==0.60.0
numpy==1.26.4
nvidia-cublas-cu12==12.1.3.1
nvidia-cuda-cupti-cu12==12.1.105
nvidia-cuda-nvrtc-cu12==12.1.105
nvidia-cuda-runtime-cu12==12.1.105
nvidia-cudnn-cu12==8.9.2.26
nvidia-cufft-cu12==11.0.2.54
nvidia-curand-cu12==10.3.2.106
nvidia-cusolver-cu12==11.4.5.107
nvidia-cusparse-cu12==12.1.0.106
nvidia-nccl-cu12==2.19.3
nvidia-nvjitlink-cu12==12.3.101
nvidia-nvtx-cu12==12.1.105
openai==1.12.0
opencv-python==4.9.0.80
openpyxl==3.1.2
oss2==2.17.0
overrides==7.7.0
packaging==24.1
pandas==2.2.0
pandocfilters==1.5.1
parso==0.8.3
peft==0.8.2
pexpect==4.9.0
phx-class-registry==4.1.0
pillow==10.2.0
platformdirs==4.2.0
prometheus-client==0.19.0
prompt-toolkit==3.0.43
protobuf==4.25.2
psutil==5.9.8
ptyprocess==0.7.0
pure-eval==0.2.2
py-cpuinfo==9.0.0
pyarrow==15.0.0
pyarrow-hotfix==0.6
pybase16384==0.3.7
pycparser==2.21
pycryptodome==3.20.0
pydantic==2.6.1
pydantic_core==2.16.2
pydeck==0.8.1b0
Pygments==2.17.2
pynvml==11.5.0
pyparsing==3.1.1
python-dateutil==2.8.2
python-json-logger==2.0.7
python-pptx==0.6.23
PyYAML==6.0.1
pyzmq==25.1.2
qtconsole==5.5.1
QtPy==2.4.1
referencing==0.33.0
regex==2023.12.25
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rich==13.4.2
rpds-py==0.17.1
safetensors==0.4.2
scikit-image==0.24.0
scipy==1.12.0
seaborn==0.13.2
Send2Trash==1.8.2
sentencepiece==0.1.99
sgmllib3k==1.0.0
simplejson==3.19.2
six==1.16.0
smmap==5.0.1
sniffio==1.3.0
sortedcontainers==2.4.0
soupsieve==2.5
stack-data==0.6.3
starlette==0.37.2
sympy==1.12
tenacity==8.2.3
termcolor==2.4.0
terminado==0.18.0
tifffile==2024.7.24
tiktoken==0.6.0
timeout-decorator==0.5.0
tinycss2==1.2.1
tokenizers==0.15.2
toml==0.10.2
tomli==2.0.1
toolz==0.12.1
torch==2.2.1
torchvision==0.17.1
tornado==6.4
tqdm==4.65.2
traitlets==5.14.1
transformers==4.39.0
transformers-stream-generator==0.0.4
triton==2.2.0
types-python-dateutil==2.8.19.20240106
typing_extensions==4.9.0
tzdata==2024.1
tzlocal==5.2
uri-template==1.3.0
urllib3==1.26.18
uvicorn==0.30.6
validators==0.22.0
watchdog==4.0.0
wcwidth==0.2.13
webcolors==1.13
webencodings==0.5.1
websocket-client==1.7.0
widgetsnbextension==4.0.10
XlsxWriter==3.1.9
xtuner==0.1.23
xxhash==3.4.1
yapf==0.40.2
yarl==1.9.4
zipp==3.17.0
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)