File size: 8,655 Bytes
d573b56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# 悟了悟了模型训练



## 一、前言

### 增量预训练(Incremental Pretraining)

增量预训练是指在一个已经预训练过的模型基础上,引入新的数据或特定领域的数据来进一步训练模型,旨在使模型适应新的领域或任务。训练数据不需要标注,模型从中学习通用特征和先验知识。

**特点**- **数据规模大**:通常需要大量的新数据,这些数据可能与原始预训练数据分布不同。
- **目标**:增强模型的整体能力和适应性,使其能够处理更广泛的任务和数据。
- **应用场景**:适用于模型需要覆盖新的领域或任务时。例如,一个通用的语言模型需要适应医疗领域的文本处理。

### 指令微调(Instruction Fine-tuning)

指令微调通过在特定任务的数据上进一步训练预训练模型,使其在特定任务上表现更好。指令微调特别关注模型对特定指令或任务的理解和执行能力。

**特点**- **数据规模小**:通常使用较小的数据集,专注于某个具体任务的数据,如情感分析、文本分类等。
- **目标**:优化模型在特定任务上的表现,使其能够更好地理解和执行特定指令。
- **应用场景**:适用于模型已经具有足够的通用知识,但需要在特定任务上进行优化时。例如,一个通用的语言模型需要在情感分析任务上表现更好。



一般而言,做"领域知识注入"时,使用指令微调会比增量预训练的效率更高,另外一般大模型泛化性已经比较好了,直接加个RAG也能用,所以如果是基于chat模型做些角色扮演、聊天机器人、学习某种风格等简单任务用微调的方式最好。

但如果你有海量的特定领域数据,或者想让模型学会某个行业深入的知识,可以试试看增量预训练。前提还是得有大量高质量的领域数据,可以是未标注过的,因为模型是去学数据的分布(续写能力)。

本模型是基于xtuner训练,基于此前数据制作一栏的数据即可直接训练,数据格式也可以参考官方文档[xtuner数据集格式和loss计算](https://github.com/InternLM/xtuner/blob/main/docs/zh_cn/user_guides/dataset_format.md)



## 二、模型训练

### 配置文件

增量预训练和指令微调训练流程都差不多,通过使用不同的配置文件来加载对应模型和数据即可。

一般要修改的就是base模型、数据源、训练超参数,每个参数的意义可以看官方的[config介绍](https://xtuner.readthedocs.io/zh-cn/latest/user_guides/config.html)

**增量预训练**

增量预训练配置文件可以参考 wulewule/xtuner_config/pretrain/internlm2_5-1_8b-chat_pretrain.py ,下面列出几个重要的

```diff
+ pretrained_model_name_or_path = '/root/models/internlm2_5-1_8b-chat' # 修改成自己的模型路径
+ data_dir="/root/wulewule/data"
+ data_files = [f'{data_dir}/heishenghua_pretraining.jsonl'] # 改成自己的数据路径
+ # prompt_template = PROMPT_TEMPLATE.internlm2_chat #增量预训练用不到
+ accumulative_counts = 1 #单卡训练切记改成1,不然模型学不会东西,切记切记!!!


## qlora的配置
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=128,
        lora_dropout=0.1,
        bias='none',
        task_type='CAUSAL_LM'))
+ #另外把两处带shuffle的改成False了,想尽量保持原始顺序去学习数据分布
```

**指令微调**

指令微调配置文件可以参考 wulewule/xtuner_config/finetune/internlm2_5_chat_1_8b_qlora_wulewule_all_test.py,下面列出几个重要的

```diff
+ pretrained_model_name_or_path = 'pretrain/merged_internlm2_5-1_8b-chat_pretrain' # 修改成自己的模型路径
+ data_dir="/root/wulewule/data"
+ data_files = [f'{data_dir}/self_cognition_100.jsonl',  f'{data_dir}/huixiangdou_conversations.jsonl'] # 改成自己的数据路径
+ prompt_template = PROMPT_TEMPLATE.internlm2_chat #internlm2_chat默认的
+ accumulative_counts = 1 #单卡训练切记改成1,不然模型学不会东西,切记切记!!!


## qlora的配置
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=128,
        lora_dropout=0.1,
        bias='none',
        task_type='CAUSAL_LM'))
+ SYSTEM = "你是悟了悟了,由xzyun2011开发的AI助手,专注于回答和《黑神话:悟空》这款游戏相关的问题,你想帮助玩家了解更多这款游戏背后的故事和文化知识。\n" #修改为自己制作数据集时的prompt
```

至于学习率等超参数,需要自己多调试,就经验而言学习了一般设置量级1e-5左右,epoch轮数最好10以下,尽量避免灾难性遗忘问题;

### 模型训练

使用了deepspeed加速训练

```
#增量预训练
xtuner train ./xtuner_config/pretrain/internlm2_5-1_8b-chat_pretrain.py  --work-dir ./pretrain --deepspeed deepspeed_zero1

#指令微调
xtuner train ./xtuner_config/finetune/internlm2_5_chat_1_8b_qlora_wulewule_all_test.py  --work-dir ./finetune --deepspeed deepspeed_zero1
```

loss可视化,读取对应目录tensorboard数据,打开http://localhost:6006/

```
#指令微调为例
tensorboard --logdir ./finetune/work_dirs/internlm2_5_chat_1_8b_qlora_wulewule_all_test.py/20241010_230522/vis_data
```

### 模型转换 + LoRA 合并

在训练完成后,我们会得到几个 `.pth` 文件,这些文件存储了 QLoRA 算法训练过程所更新的参数,而**不是**模型的全部参数。因此我们需要将这些 `.pth` 文件转换为 HuggingFace 格式,并合并入原始的语言模型权重中。

#### 模型转换

XTuner 已经集成好了将模型转换为 HuggingFace 格式的工具,我们只需要执行,pth_file改为自己需要转换的LoRA模型

```
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU

## 需要看loss曲线和测试集表现,选择对应的模型
##指令微调为例子,先获取最后保存的一个pth文件
pth_file=`ls -t ./finetune/internlm2_5_chat_1_8b_qlora_wulewule_all_test.py/*.pth | head -n 1| sed 's/:$//' `
# 转换格式
xtuner convert pth_to_hf ./internlm2_5_chat_1_8b_qlora_wulewule_all_test.py ${pth_file} ./hf
```

#### LoRA 合并

XTuner 也已经集成好了合并 LoRA 权重的工具,我们只需执行如下指令

```
# 合并参数
xtuner convert merge /root/models/internlm2_5-1_8b-chat ./hf /root/wulewule/models/wulewule_v1_1_8b --max-shard-size 2GB
```

与转换命令类似,该条合并参数命令会读取原始参数路径 `/root/models/internlm2_5-1_8b-chat` 以及转换为 hf 格式的部分参数路径 `./h`,将两部分参数合并后保存于 `/root/wulewule/models/wulewule_v1_1_8b`,其中每个参数切片的最大文件大小为 2GB。

### 与模型对话

在合并权重后,为了更好地体会到模型的能力,XTuner 也集成了与模型对话的工具。通过如下命令,便可以启动一个与模型对话的简易 Demo。

```
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner chat ./merged --prompt-template internlm2_chat --system "your system"
```

其中 `./merged` 是合并后的权重路径,`--prompt-template internlm2_chat` 指定了对话模板为 InternLM2-Chat,`--system` 则是指定了与模型对话时的 System Prompt,保持和数据训练时一致。