File size: 21,068 Bytes
ae5d6bd
 
 
 
 
90f3266
 
ae5d6bd
 
 
 
 
 
 
90f3266
ae5d6bd
90f3266
 
 
 
ae5d6bd
90f3266
 
 
 
 
ae5d6bd
 
 
 
 
 
 
 
 
 
 
90f3266
ae5d6bd
 
 
 
 
 
 
 
 
 
90f3266
 
ae5d6bd
 
 
 
 
 
 
 
 
 
 
90f3266
ae5d6bd
 
 
 
 
 
 
 
 
90f3266
ae5d6bd
 
 
 
 
90f3266
ae5d6bd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90f3266
 
ae5d6bd
 
 
 
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# UnrealEngineGPT: 虚幻引擎对话式大语言模型

<div align="left">

![GitHub Repo stars](https://img.shields.io/github/stars/jiayaozhang/UnrealEngineGPT?style=social)
[![Generic badge](https://img.shields.io/badge/🤗-Huggingface%20Repo-green.svg)](https://huggingface.co/Jiayao)
[![Generic badge](https://img.shields.io/badge/🔥-Modelscope-white)](https://www.modelscope.cn/profile/Jannie)

</div>


欢迎加入虚幻引擎大模型的学习🤗。


## News: 😎 开源模型

**在1/2*V100上进行训练**,经过中文词表扩充、增量预训练、多轮指令微调。该项目也支持对Baichuan、Qwen、InternLM、LLaMA、Falcon等模型进行高效增量预训练。
🔔 使用本项目的训练代码,以及上述训练数据,我们训练并开源了以下模型。

中文模型:

| 模型                                                                             | Huggingface                                | Modelscope|
|--------------------------------------------------------------------------------|-------------------------------------|------------|
| InternLM-UEGPT-7b    | [Huggingface-internLM2-7b](https://huggingface.co/Jiayao/UEGPT-internlm-7b-qlora-sft-merge/tree/main)  | [UEGPT-internLM2-7b](https://www.modelscope.cn/models/Jannie/UEGPT-internlm-7b-qlora-sft-merge/files) |  
| InternLM-UEGPT-20b   | [Huggingface-internLM2-20b](https://huggingface.co/Jiayao/UnrealGPT-internlm-20b-qlora-sft-merge) | [Modelscope-internLM2-20b](https://www.modelscope.cn/models/Jannie/UEGPT-internlm-20b-qlora-sft-merge/files)|  
| UEGPT-Datasets       | [Huggingface-UEGPT-Datasets](https://huggingface.co/datasets/Jiayao/UEGPT-Datasets)     |[Modelscope-UEGPT-Datasets](https://www.modelscope.cn/datasets/Jannie/UEGPT-Datasets/files)     |  


## 相关项目

| Project                                                                                        | Description                                                                                    |
|------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| [InternLM Notes](https://github.com/jiayaozhang/InternLM_Notes)  | RAG检索增强生成,支持使用QLoRA增量预训练大模型推理优化、大模型参数高效微调(PEFT)、大模型上下文扩展|
| [LongQLoRA](https://github.com/yangjianxin1/LongQLoRA) | 大模型长度扩展项目,可在单卡V100上将LLaMA-13B的长度扩展至8192,且性能逼近MPT-8K                                            |

## 项目简介


**虚幻引擎对话式大语言模型** 是一个开源的虚幻引擎大语言模型项目,支持QLoRA和全量参数微调InternLM等开源模型。

正如项目名称一样,希望本项目能够为为虚幻引擎社区尽绵薄之力,促进游戏以及游戏引擎的发展。
如果你的训练资源有限,我们极力推荐使用QLoRA的指令微调方式,因为我们在Open LLM Leaderboard上验证了该方法的有效性。


🔔 本项目主要内容如下:
- 📗 支持全量参数指令微调、QLoRA低成本高效指令微调、其中QLoRA是我们主推的一种高效的训练方式。
- 📗 支持绝大部分主流的开源大模型,如Baichuan2、CodeLLaMA、LLaMA2、LLaMA、Qwen、Baichuan、ChatGLM2、InternLM、Ziya、Bloom、XVERSE等。
- 📗 支持lora与base model进行权重合并,推理更便捷。
- 📗️ 模型裁剪:通过[LLMPruner:大语言模型裁剪工具](https://github.com/yangjianxin1/LLMPruner) ,开源[裁剪后的Bloom模型权重](https://huggingface.co/Jiayao) 。在保留预训练中文知识的前提下,有效减少模型参数量,降低训练成本,提高训练效率。
- 📗 开源[UEGPT系列指令微调模型权重](https://huggingface.co/Jiayao) 。
- 📗 在Open LLM Leaderboard上验证了QLoRA训练流程的有效性。


## 安装环境
在requirements.txt下固定了几个主要的python包的版本,执行如下脚本即可。

**注意:Baichuan2需要安装pytorch 2.0。除Baichuan2以外,其他模型的训练,我们均在torch==1.13上进行训练。**
```bash
pip install requirements.txt
```

<!-- ## 模型列表

🔔 使用本项目的训练代码,以及上述训练数据,我们训练并开源了以下模型。

中文模型:

| 模型                                                                             | 基座模型                                | Max Length |
|--------------------------------------------------------------------------------|-------------------------------------|------------|
| [InternLM-UEGPT-7b](https://huggingface.co/YeungNLP/firefly-baichuan2-13b) | internlm/internlm-7b     |1024     |  
| [InternLM-UEGPT-20b](https://huggingface.co/YeungNLP/firefly-baichuan-13b)   | internlm/internlm-20b      |1024     |  
 -->

## 训练数据

| [moss-003-sft-data](https://huggingface.co/datasets/YeungNLP/moss-003-sft-data)                               | 由复旦大学MOSS团队开源的中英文多轮对话数据,包含100万+数据                                                                       

🔔 目前本项目参考复旦大学MOSS团队开源的中英文多轮对话数据统一的数据格式,整理了上千条虚幻引擎问答多轮数据对话

训练数据为jsonl格式,每一行的数据格式如下,其中conversation字段是必需的,可以根据实际需求添加或删除其他字段。
可以参考项目中的data/dummy_data.jsonl文件。
```json
  {
    "conversation_id": 390,
    "category": "Brainstorming",
    "conversation": [
      {
        "human": "如何在虚幻引擎中实现水面波纹效果?",
        "assistant": "实现水面波纹效果在虚幻引擎中通常涉及材质编辑器的使用,以及可能应用一些动态模拟技术。以下是一个基础的步骤指南,介绍如何在虚幻引擎中创建水面波纹效果:\n\n### 材质创建\n\n1. **创建水面材质**:首先,你需要创建一个新的材质,用来应用到你的水面对象上。\n   \n2. **使用波纹纹理**:找到适合的波纹纹理或者使用程序生成的模式,比如使用Perlin噪声或简单的正弦波函数来模拟波纹。\n\n3. **纹理坐标和变换**:使用材质编辑器中的纹理坐标(Texture Coordinates)节点与时间(Time)节点,结合一些数学运算,来对纹理进行动态变换,产生波动效果。\n\n4. **反射与折射**:利用虚幻的反射和折射功能使水面更逼真。通常,通过设置材质的反射(Specular)和粗糙度(Roughness)参数,以及可能的折射参数来模拟水光效果。\n\n5. **透明与深度效果**:为了使水面更逼真,还需要调整透明度(Opacity)以及深度效果,这可能包括水底颜色渐变、深度模糊等。\n\n### 动态波纹\n\n1. **顶点位移**:如果需要波纹影响水面的形态(3D效果),可以使用顶点位移(Vertex Displacement)技术,根据波纹纹理来上下移动水面的顶点。\n\n2. **材质参数调整**:创建材质实例,允许在游戏运行时动态调整波纹的强度、速度等。\n\n3. **触发波纹**:对于交互性的波纹(例如物体掉入水面),需要编写蓝图或C++代码来在特定位置触发波纹效果,可以通过在材质中设置参数,并用蓝图或代码动态更新它们来实现。\n\n### 更高级的技术\n\n- **物理模拟**:对于更高级的波纹效果,可以实现基于物理的模拟,如采用一个动态模拟系统或使用顶点着色器和计算着色器进行模拟。\n\n- **涟漪扩散**:为了模拟从一个点向外扩散的涟漪效果,可以采用某种扩散算法,并将其表现在水面材质上。\n\n- **多层波纹效果**:通过叠加不同的波纹图层来创建更复杂的波纹效果。\n\n- **动态环境交互**:实现环境要素(如风、雨滴)与水面交互产生的动态波纹效果。\n\n在实现水面波纹效果时,监视性能也很重要,因为这些效果有时会非常消耗GPU资源。务必管理好材质的复杂度,并考虑只在玩家视野范围内使用更高级的效果,而在远处采用更简化的表现。"
     },
     {
        "human": "虚幻引擎中的自适应曝光是如何调整场景曝光的?",
        "assistant": "对于大量的问题和广泛的主题,回答每个问题都是非常耗时的。这样的问题列表看起来像是为了开发或学习虚幻引擎(Unreal Engine)渲染技术的目的而准备的。为了提供一些有用的信息,我将试着总结出关键的回答,这样可以涵盖大部分问到的主题。\n\n**虚幻引擎渲染管线概述:**\n虚幻引擎的渲染管线负责将3D场景转换为平面图像。主要步骤包括场景几何体的提取、光照和阴影的计算、材质的应用、以及最终的图像后处理。\n\n**创建和编辑材质:**\n材质是定义对象表面外观,如颜色、纹理和光泽等的属性。在虚幻引擎中,你可以使用材质编辑器来创建和编辑材质,它提供了一个可视化的节点网络来调整材质属性。\n\n**Post-Processing效果:**\n后期处理效果涉及到在3D渲染后对图像进行的处理,这包括颜色校正、布鲁光(Bloom)、景深(Depth of Field)、HDR曝光、镜面折射和反射等效果。\n\n**虚幻引擎粒子系统:**\n虚幻引擎提供了强大的Niagara和Cascade粒子系统,用于创建如火、烟、雾、尘埃等效果。这可以通过蓝图或材质与粒子参数交互进行增强。\n\n**光线追踪技术:**\n虚幻引擎支持实时光线追踪,它提供了更逼真的光影效果,像几乎真实的反射、阴影、折射和全局光照(Global Illumination, GI)。\n\n**阴影技术:**\n虚幻引擎支持多种阴影技术,包括静态阴影贴图、动态阴影和软阴影。这些技术考虑了不同光源和物体的特性来生成逼真的阴影。\n\n**全局光照解决方案:**\n全局光照是指光在场景中的多次散射。虚幻引擎提供了静态的光照贴图以及动态GI解决方案,如LPV(Light Propagation Volumes)。\n\n**图像空间光线追踪 (ISRT) 和 GPU粒子系统:**\nISRT允许在图像空间来模拟更复杂的光影效果。GPU粒子系统利用了图形处理器的强大计算能力,可以实现大量粒子实时模拟。\n\n**抗锯齿技术:**\n虚幻引擎支持多种抗锯齿技术,包括传统的MSAA、更现代的技术如FXAA、TXAA和MLAA等。\n\n**渲染优化技术:**\n为了提高性能,虚幻引擎实现了多种优化技术,例如LOD系统(Level of Detail,细节层次)、剔除(Culling,移除视野外的物体)、纹理压缩和流式加载等。\n\n**动态天气系统和环境效果:**\n动态天气系统可以通过改变光照、粒子系统(如下雨或下雪),以及天空盒的动态变化来实现。环境效果则可以通过材料更改(如湿地效果)和PBR材料的逼真性来提升。"
     },
     {
        "human": "如何在虚幻引擎中创建动态的火焰和爆炸效果?",
        "assistant": "创建和编辑材质的过程依赖于虚幻引擎的材质编辑器。这是一个非常直观的界面,它允许用户通过材质图(Material Graph)来创建和编辑材质。在这个图中,材质的各个部分是通过节点表示的。每个节点代表了一种材质属性,比如颜色、纹理、透明度、高光等,这些节点可以通过线缆相连,以定义材质的最终外观。\n\n以下是创建和编辑材质的基本步骤:\n\n1. 创建新材质:\n   - 在内容浏览器中右键单击,选择“材质”选项。\n   - 这将创建一个新的材质资产,并在材质编辑器中打开它。\n\n2. 编辑材质属性:\n   - 使用材质编辑器左侧的节点面板来添加各种节点到材质图中。\n   - 您可以添加纹理采样器节点来使用贴图,常量节点来定义颜色或数值,以及各种材质函数节点来实现更复杂的效果。\n\n3. 连接节点:\n   - 节点之间的连接定义了材质的运算逻辑。拖拽节点之间的针脚来连接它们。\n   - 您需要将结果连接到材质的输出节点,这些输出定义了材质在光照、颜色、金属度、粗糙度等方面的表现。\n\n4. 参数化材质:\n   - 通过添加材质参数,比如“参数化纹理”、“参数变量”等,您可以创建可以在蓝图中或在材质实例中动态调整的材质。\n   - 参数化让您可以重用同一个材质,通过更改参数来实现不同的外观,这非常有用。\n\n5. 预览和调整:\n   - 您可以实时预览材质在材质编辑器中的球体或立方体预览上的效果。\n   - 根据预览进行实时调整,直到您满意为止。\n\n6. 保存并应用:\n   - 一旦完成材质的编辑,点击“保存”按钮来保存您的工作。\n   - 您可以将此材质拖动到场景中的对象上,或者在静态网格的材质槽中指定它。\n\n请记住,材质制作是一个迭代过程,可能需要多次调整和预览以达到理想的效果。虚幻引擎的材质编辑器支持PBR(基于物理的渲染)工作流,使得创建的材质可以更逼真地模拟真实世界中的物体表面。"
     },
     {
        "human": "虚幻引擎中的LOD系统如何影响渲染性能?",
        "assistant": "Unreal Engine(虚幻引擎)提供了一系列功能来优化渲染渲染性能,其中LOD系统(Level Of Detail,详细等级)是很重要的一部分。LOD系统是通过为在不同距离上观察的对象提供不同的细节层次,从而优化渲染性能。\n\nLOD 系统如何影响渲染性能:\n\n1. **模型复杂度降低**:当物体距离摄像机较远时,渲染器会选择使用更低细节的模型。这些模型通常拥有较少的顶点和面片,从而减少了GPU的负担。\n\n2. **渲染调用减少**:如果多个远处物体使用相同的LOD层级,可以将它们的绘制调用合并为单次调用,从而降低CPU负担。\n\n3. **纹理贴图和材质复杂度降低**:与模型类似,远处物体也可以使用更低分辨率的纹理和简化的材质,这进一步降低了显存的使用量和纹理采样的性能消耗。\n\n4. **影子及反射代理**:面向远距离物体时,可以采用更低分辨率的影子贴图(Shadow Maps)和反射代理(Reflection Probes),从而达到性能节省的目的。\n\n5. **发卡负载均衡**:通过根据摄像机的视角和距离自动调整模型的细节级别,LOD系统可以在不牺牲太多视觉效果的情况下对发卡负载进行均衡。\n\n6. **流畅的视觉体验**:设置不同LOD阈值可以在性能和视觉质量之间取得平衡。当玩家在游戏中移动时,通过平滑的转换来确保不会有突变的视觉变化。\n\n为了最大化渲染的性能,通常需要对物体进行LOD的设置,确保在视觉效果可接受的前提下最小化性能的消耗。Unreal Engine 提供了自动和手动创建LOD的工具,开发者可以根据项目的需要来设定不同级别的LOD,以获得最佳的性能和视觉效果。"
     }
    ]
  }
```




## 模型训练



目前支持全量参数指令微调、QLoRA指令微调。我们将训练中使用的各种组件抽取出来,以便后续的扩展和优化,详见component目录下的实现。训练时的参数配置存储在train_args目录下,方便统一管理和更改。大家可以在train_args目录下查看不同模型的训练配置。

### 数据格式
训练时,我们将多轮对话拼接成如下格式,然后进行tokenize。其中<s\>表示bos_token,</s\> 表示eos_token。
```
<s>input1</s>target1</s>input2</s>target2</s>...
```
在计算loss时,我们通过mask的方式,input部分的loss不参与参数更新,只有“target</s>”部分的loss参与参数更新。
这种方式充分利用了模型并行计算的优势,训练更加高效,且多轮对话中的每个target部分都参与了训练,训练更充分。
否则,就需要把一个n轮对话,拆分成n条数据,且只计算最后一个target的loss,大大降低了训练效率。

### 全量参数微调
💻 执行如下命令即可进行全量参数微调:
```bash
deepspeed --num_gpus={num_gpus} train.py --train_args_file train_args/sft.json
```

📝 train_args/sft.json中的主要参数说明如下,以下参数可以根据需求进行修改,其他参数建议不做修改:
- output_dir:训练输出目录,存储checkpoint、tokenizer、tensorboard等
- model_name_or_path:预训练模型的本地目录,或者在huggingface上的模型名称。
- train_file:训练数据集路径。可以使用data/dummy_data.jsonl进行debug。
- num_train_epochs:训练的轮次。如果数据量足够大,一般建议只训一个epoch。
- per_device_train_batch_size:每张显卡的batch size。
- gradient_accumulation_steps:梯度累计步数。global batch=num_gpus * per_device_train_batch_size * gradient_accumulation_steps。
- gradient_checkpointing:如果显存捉襟见肘,可以开启。以时间换空间,模型不缓存激活状态,会进行两次forward计算,以节省显存。
- learning_rate:学习率。全量参数微调的时候,建议小一些,1e-5或5e-6。
- max_seq_length:训练时的最大长度。按照自己的设备进行设置,越长需要占用越多显存。
- logging_steps:每隔多少步统计一次train loss。
- save_steps:每隔多少步保存一个模型。
- save_total_limit:output_dir目录中最多保存多少个checkpoint,超出则会将最旧的删除。
- lr_scheduler_type:学习率变化策略。
- warmup_steps:warm up步数。学习率经过多少步,增长到指定的数值。
- optim:优化器。如果是全量参数微调,建议使用adamw_hf。
- seed:随机种子,用于复现实验结果。
- fp16:使用使用fp16混合精度。V100建议开启。
- bf16:使用使用bf16混合精度。A100建议开启。



### QLoRA微调

关于QLoRA的详细介绍可参考文章:[【QLoRA实战】使用单卡高效微调bloom-7b1,效果惊艳](https://mp.weixin.qq.com/s/DED7yeiE0DibsVzTmMeDOw)

QLoRA通过4-bit的nf4量化,且加入更多adapter,在大幅减少显存消耗的同时,尽可能逼近全量参数微调的效果。
QLoRA论文指出,该方法可以在一张V100上对33B的模型进行微调,并且性能逼近全量参数微调。

我们在bloom-7b1上使用qlora,adapter的参数量约1.2亿,超过bert-base模型参数量,可以在V100上使用1024的长度进行训练。

💻 单卡时建议使用python命令启动脚本:
```bash
python train_qlora.py --train_args_file train_args/qlora/baichuan-7b-sft-qlora.json
```

💻 多卡时使用torchrun命令启动脚本:
```bash
torchrun --nproc_per_node={num_gpus} train_qlora.py --train_args_file train_args/qlora/baichuan-7b-sft-qlora.json
```

📝 train_args/sft-qlora.json中的主要参数说明如下,基本与全量微调的参数一致,几个较为特殊:
- lora_rank:qlora矩阵的秩。一般设置为8、16、32、64等,在qlora论文中作者设为64。越大则参与训练的参数量越大,一般来说效果会更好,但需要更多显存,。
- lora_alpha: qlora中的缩放参数。一般设为16、32即可。
- lora_dropout: lora权重的dropout rate。
- learning_rate:qlora中的学习率设置更大一些,一般为1e-4、2e-4。


## 模型使用

### 权重合并
如果使用LoRA或者QLoRA进行训练,本项目仅保存adapter的权重和配置文件,需要将adapter权重与base model进行合并。脚本见script/merge_lora.py

### 模型推理
我们提供了单轮对话和多轮对话的脚本,详见script/chat目录,该脚本可同时兼容本项目训练的所有模型进行推理,不适用于非本项目训练的模型。
```bash
cd script/chat
python single_chat.py
```

生成脚本中的top_p、temperature、repetition_penalty、do_sample等参数对模型的生成效果影响较大,可按照自己的使用场景进行调试修改。

推理脚本中支持使用base model和adapter进行推理,缺点是每次启动脚本都需要合并一次权重,等待时间较久。

支持使用4bit进行推理,显存要求低,效果会略有下降。

### 服务部署
本项目支持将模型部署成HTTP服务,脚本在script/http下,使用flask进行开发。start_service.py为启动服务,post为发送请求,可按需进行修改。


## 生成效果

下面的样例均为UEGPT-InternLM2-20b模型所生成,未经修改,仅供参考。




</details>


## InternLM大模型与虚幻引擎在线结合

后期把虚幻引擎和书生大模型联合,可以实时调试,之后会把虚幻的项目工程放出来

😎Stay tune!

license: Apache License 2.0