480 | ```
481 |
482 |
483 | ### 2.3 魔乐社区平台
484 |
485 | 魔乐社区(Modelers)是一个提供多样化、开源模型的平台,旨在促进开发者和研究人员在最先进的模型和流行应用上进行协作。
486 |
487 | #### 2.3.1 下载internlm2_5-chat-1_8b模型
488 |
489 | > 这里我们可以继续使用我们刚刚创建的InterStudio开发机
490 | ```
491 | cd /
492 | mkdir ml_demo
493 | cd ml_demo
494 | ```
495 |
496 | 然后我们可以下载该模型,这里
497 |
498 | ```
499 | # 确保安装git-lfs 保证大文件的正常下载
500 | apt-get install git-lfs
501 | git lfs install
502 | # clone 仓库
503 | git clone https://modelers.cn/Intern/internlm2_5-1_8b-chat.git
504 | ```
505 |
506 | 刷新一下文件夹,即可在ml_demo中找到下载好的模型文件,在魔乐社区中,还推荐了一个新的深度学习开发套件[openMind Library](https://modelers.cn/docs/zh/openmind-library/overview.html),除了常用的Transforms的API,也可以探索如何使用openMind来加载模型
507 |
508 | ```python
509 | # 确保按指南安装好openmind后
510 | from openmind import AutoModel
511 | model = AutoModel.from_pretrained("Intern/internlm2_5-1_8b-chat", trust_remote_code="True")
512 | ```
513 |
514 | >openMind Library是一个深度学习开发套件,通过简单易用的API支持模型预训练、微调、推理等流程。
515 | >openMind Library通过一套接口兼容PyTorch和MindSpore等主流框架,同时原生支持昇腾NPU处理器。
516 |
517 | #### 2.3.2 上传模型
518 | 在魔乐社区一般有两种方法,第一种是安装好openmid后使用openmind的API来上传文件,另一个就是用git命令来推送文件,跟一般的git工作流相类似。可参考[上传文件 | 魔乐社区](https://modelers.cn/docs/zh/openmind-hub-client/basic_tutorial/upload.html)
519 |
520 | ### 2.4 始智AI平台
521 |
522 | 始智AI平台(wisemodel)是一个中立开放的AI开源社区, 是一个提供多样化开源模型、数据集以及训练和微调的一站式平台。
523 |
524 | #### 2.4.1 下载llava-internlm2-7B模型
525 |
526 | 注册好该平台后,我们可以在创建好的InternStudio开发机下下载模型
527 |
528 | ```bash
529 | cd /
530 | mkdir wise_model
531 | cd wise_model
532 | ```
533 |
534 | 假设的账户名是username,那么可以用以下方式,下载公有仓库的模型
535 |
536 | ```bash
537 | git lfs install
538 | git clone https://www.wisemodel.cn/username/llava-internlm2-7b.git
539 | ```
540 |
541 | 如果涉及到私有仓库,需要创建git token进行操作,具体请参考[上传文件 | 始智AI-wisemodel](https://wisemodel.cn/docs/%E6%A8%A1%E5%9E%8B%E4%B8%8A%E4%BC%A0)
542 |
543 | #### 2.4.2 上传模型
544 |
545 | 假设你的模型文件位于/work/my_model_dir本地目录下:
546 |
547 | ```bash
548 | cd my_test_model #进入同步模型仓库的目录
549 | cp -rf /work/my_model_dir/* . #从/work/my_model_dir本地目录把文件拷贝到模型仓库
550 | git add -A . #执行更新git目录
551 | git commit -m "commit message" #合并文件并填写更新说明
552 | git push #将本地文件上传更新
553 | ```
554 |
555 |
--------------------------------------------------------------------------------
/docs/L0/maas/task.md:
--------------------------------------------------------------------------------
1 | # 闯关任务
2 |
3 | 闯关任务需要在关键步骤当中截图!
4 |
5 | | 任务 | 描述 | 时间 |
6 | | --- | --- | --- |
7 | | [模型下载](https://huggingface.co/internlm/internlm2-chat-1_8b) | 使用Hugging Face平台、魔搭社区平台(可选)和魔乐社区平台(可选)下载文档中提到的模型(至少需要下载config.json文件、model.safetensors.index.json文件),请在必要的步骤以及结果当中截图。 | 20min |
8 | | 模型上传(可选) | 将我们下载好的config.json文件(也自行添加其他模型相关文件)上传到对应HF平台和魔搭社区平台,并截图。 | 10min |
9 | | Space上传(可选) | 在HF平台上使用Spaces并把intern_cobuild部署成功,关键步骤截图。 | 10min |
10 |
11 |
12 | 优秀作业必做可选内容
13 | 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 50 算力点奖励!!!
14 |
15 | 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
16 |
--------------------------------------------------------------------------------
/docs/L1/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InternLM/Tutorial/abda6a585ad698e8c9acf6512c65f89eea7d4eda/docs/L1/.gitkeep
--------------------------------------------------------------------------------
/docs/L1/Evaluation/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # OpenCompass 评测
5 |
6 | 本节课程聚焦于大语言模型的评测,在后续的课程中我们将介绍多模态大模型的评测方法。
7 |
8 | OpenCompass 提供了 **API 模式评测**和**本地直接评测**两种方式。其中 API 模式评测针对那些以 API 服务形式部署的模型,而本地直接评测则面向那些可以获取到模型权重文件的情况。
9 |
10 | 我们首先在训练营提供的开发机上创建用于评测 conda 环境:
11 |
12 | ```bash
13 | conda create -n opencompass python=3.10
14 | conda activate opencompass
15 |
16 | cd /root
17 | git clone -b 0.3.3 https://github.com/open-compass/opencompass
18 | cd opencompass
19 | pip install -e .
20 | pip install -r requirements.txt
21 | pip install huggingface_hub==0.25.2
22 |
23 | pip install importlib-metadata
24 | ```
25 |
26 | 更多使用说明,请参考 OpenCompass [官方文档](https://opencompass.readthedocs.io/en/latest/tutorial.html)。
27 |
28 |
29 |
30 | ## 评测 API 模型
31 |
32 | 如果你想要评测通过 API 访问的大语言模型,整个过程其实很简单。首先你需要获取模型的 API 密钥(API Key)和接口地址。以 OpenAI 的 GPT 模型为例,你只需要在 OpenAI 官网申请一个 API Key,然后在评测配置文件中设置好这个密钥和相应的模型参数就可以开始评测了。评测过程中,评测框架会自动向模型服务发送测试用例,获取模型的回复并进行打分分析。整个过程你不需要准备任何模型文件,也不用担心本地计算资源是否足够,只要确保网络连接正常即可。
33 |
34 |
35 | 考虑到 openai 的 API 服务暂时在国内无法直接使用,我们这里以评测 internlm 模型为例,介绍如何评测 API 模型。
36 |
37 |
38 | 1) 打开网站浦语官方地址 https://internlm.intern-ai.org.cn/api/document 获得 api key 和 api 服务地址 (也可以从第三方平台 [硅基流动](https://siliconflow.cn/zh-cn/siliconcloud) 获取), 在终端中运行:
39 |
40 | ```bash
41 | export INTERNLM_API_KEY=xxxxxxxxxxxxxxxxxxxxxxx # 填入你申请的 API Key
42 | ```
43 |
44 | 2) 配置模型: 在终端中运行 `cd /root/opencompass/` 和 `touch opencompass/configs/models/openai/puyu_api.py`, 然后打开文件, 贴入以下代码:
45 |
46 |
47 | ```python
48 | import os
49 | from opencompass.models import OpenAISDK
50 |
51 |
52 | internlm_url = 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1/' # 你前面获得的 api 服务地址
53 | internlm_api_key = os.getenv('INTERNLM_API_KEY')
54 |
55 | models = [
56 | dict(
57 | # abbr='internlm2.5-latest',
58 | type=OpenAISDK,
59 | path='internlm2.5-latest', # 请求服务时的 model name
60 | # 换成自己申请的APIkey
61 | key=internlm_api_key, # API key
62 | openai_api_base=internlm_url, # 服务地址
63 | rpm_verbose=True, # 是否打印请求速率
64 | query_per_second=0.16, # 服务请求速率
65 | max_out_len=1024, # 最大输出长度
66 | max_seq_len=4096, # 最大输入长度
67 | temperature=0.01, # 生成温度
68 | batch_size=1, # 批处理大小
69 | retry=3, # 重试次数
70 | )
71 | ]
72 | ```
73 |
74 | 3) 配置数据集: 在终端中运行 `cd /root/opencompass/` 和 `touch opencompass/configs/datasets/demo/demo_cmmlu_chat_gen.py`, 然后打开文件, 贴入以下代码:
75 |
76 | ```python
77 | from mmengine import read_base
78 |
79 | with read_base():
80 | from ..cmmlu.cmmlu_gen_c13365 import cmmlu_datasets
81 |
82 |
83 | # 每个数据集只取前2个样本进行评测
84 | for d in cmmlu_datasets:
85 | d['abbr'] = 'demo_' + d['abbr']
86 | d['reader_cfg']['test_range'] = '[0:1]' # 这里每个数据集只取1个样本, 方便快速评测.
87 |
88 |
89 | ```
90 | 这样我们使用了 CMMLU Benchmark 的每个子数据集的 1 个样本进行评测.
91 |
92 |
93 | 完成配置后, 在终端中运行: `python run.py --models puyu_api.py --datasets demo_cmmlu_chat_gen.py --debug`. 预计运行10分钟后, 得到结果:
94 |
95 | 
96 |
97 |
98 |
99 |
100 |
101 |
102 | ## 评测本地模型
103 |
104 |
105 | 如果你想要评测本地部署的大语言模型,首先需要获取到完整的模型权重文件。以开源模型为例,你可以从 Hugging Face 等平台下载模型文件。接下来,你需要准备足够的计算资源,比如至少一张显存够大的 GPU,因为模型文件通常都比较大。有了模型和硬件后,你需要在评测配置文件中指定模型路径和相关参数,然后评测框架就会自动加载模型并开始评测。这种评测方式虽然前期准备工作相对繁琐,需要考虑硬件资源,但好处是评测过程完全在本地完成,不依赖网络状态,而且你可以更灵活地调整模型参数,深入了解模型的性能表现。这种方式特别适合需要深入研究模型性能或进行模型改进的研发人员。
106 |
107 |
108 | 我们接下以评测 InternLM2.5-1.8B-Chat 在 C-Eval 数据集上的性能为例,介绍如何评测本地模型。
109 |
110 | ### 相关配置
111 |
112 |
113 | 安装相关软件包:
114 |
115 | ```bash
116 | cd /root/opencompass
117 | conda activate opencompass
118 | conda install pytorch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 pytorch-cuda=12.1 -c pytorch -c nvidia -y
119 | apt-get update
120 | apt-get install cmake
121 | pip install protobuf==4.25.3
122 | ```
123 |
124 | 为了解决一些本地评测时出现的报错问题,我们还需要重装一些 python 库
125 |
126 | ```bash
127 | pip uninstall numpy -y
128 | pip install "numpy<2.0.0,>=1.23.4"
129 | pip uninstall pandas -y
130 | pip install "pandas<2.0.0"
131 | pip install onnxscript
132 | pip uninstall transformers -y
133 | pip install transformers==4.39.0
134 | ```
135 |
136 | 为了方便评测,我们首先将数据集下载到本地:
137 |
138 | ```bash
139 | cp /share/temp/datasets/OpenCompassData-core-20231110.zip /root/opencompass/
140 | unzip OpenCompassData-core-20231110.zip
141 | ```
142 | 将会在 OpenCompass 下看到data文件夹.
143 |
144 |
145 |
146 | ### 加载本地模型进行评测
147 |
148 |
149 | 在 OpenCompass 中,模型和数据集的配置文件都存放在 `configs` 文件夹下。我们可以通过运行 `list_configs` 命令列出所有跟 InternLM 及 C-Eval 相关的配置。
150 |
151 | ```bash
152 | python tools/list_configs.py internlm ceval
153 | ```
154 |
155 | 打开 opencompass 文件夹下 `configs/models/hf_internlm/的 hf_internlm2_5_1_8b_chat.py` 文件, 修改如下:
156 |
157 | ```python
158 | from opencompass.models import HuggingFacewithChatTemplate
159 |
160 | models = [
161 | dict(
162 | type=HuggingFacewithChatTemplate,
163 | abbr='internlm2_5-1_8b-chat-hf',
164 | path='/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat/',
165 | max_out_len=2048,
166 | batch_size=8,
167 | run_cfg=dict(num_gpus=1),
168 | )
169 | ]
170 |
171 | # python run.py --datasets ceval_gen --models hf_internlm2_5_1_8b_chat --debug
172 | ```
173 |
174 | 可以通过以下命令评测 InternLM2.5-1.8B-Chat 模型在 C-Eval 数据集上的性能。由于 OpenCompass 默认并行启动评估过程,我们可以在第一次运行时以 --debug 模式启动评估,并检查是否存在问题。在 --debug 模式下,任务将按顺序执行,并实时打印输出。
175 |
176 | ```bash
177 | python run.py --datasets ceval_gen --models hf_internlm2_5_1_8b_chat --debug
178 | # 如果出现 rouge 导入报错, 请 pip uninstall rouge 之后再次安装 pip install rouge==1.0.1 可解决问题.
179 | ```
180 | 评测比较费时, 预计2~4个小时评测完成后,将会看到:
181 |
182 | 
183 |
184 |
185 | 我们也可以使用配置文件来指定数据集和模型,例如:
186 |
187 | ```bash
188 | cd /root/opencompass/configs/
189 | touch eval_tutorial_demo.py
190 | ```
191 |
192 | 打开 `eval_tutorial_demo.py` 贴入以下代码
193 |
194 | ```python
195 | from mmengine.config import read_base
196 |
197 | with read_base():
198 | from .datasets.ceval.ceval_gen import ceval_datasets
199 | from .models.hf_internlm.hf_internlm2_5_1_8b_chat import models as hf_internlm2_5_1_8b_chat_models
200 |
201 | datasets = ceval_datasets
202 | models = hf_internlm2_5_1_8b_chat_models
203 | ```
204 |
205 | 这样我们指定了评测的模型和数据集,然后运行
206 |
207 | ```bash
208 | python run.py configs/eval_tutorial_demo.py --debug
209 | ```
210 |
211 |
212 | ## 将本地模型通过部署成API服务再评测
213 |
214 | 前面我们介绍了如何评测 API 模型和本地模型, 现在我们介绍如何将本地模型部署成 API 服务, 然后通过评测 API 服务的方式来评测本地模型. OpenCompass 通过其设计,不会真正区分开源模型和 API 模型。您可以使用相同的方式甚至在一个设置中评估这两种模型类型。
215 |
216 | 首先打开一个终端, 安装和部署模型:
217 |
218 | ```bash
219 | pip install lmdeploy==0.6.1 openai==1.52.0
220 |
221 | lmdeploy serve api_server /share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat/ --server-port 23333
222 | ```
223 |
224 | 成功部署以后会看到如下输出:
225 | ```
226 | [WARNING] gemm_config.in is not found; using default GEMM algo
227 | HINT: Please open http://0.0.0.0:23333 in a browser for detailed api usage!!!
228 | HINT: Please open http://0.0.0.0:23333 in a browser for detailed api usage!!!
229 | HINT: Please open http://0.0.0.0:23333 in a browser for detailed api usage!!!
230 | INFO: Started server process [59833]
231 | INFO: Waiting for application startup.
232 | INFO: Application startup complete.
233 | INFO: Uvicorn running on http://0.0.0.0:23333 (Press CTRL+C to quit)
234 | INFO: 127.0.0.1:38584 - "POST /v1/chat/completions HTTP/1.1" 200 OK
235 | ```
236 |
237 |
238 | 新开一个终端, 使用以下 Python 代码获取由 LMDeploy 注册的模型名称:
239 |
240 | ```python
241 | from openai import OpenAI
242 | client = OpenAI(
243 | api_key='sk-123456', # 可以设置成随意的字符串
244 | base_url="http://0.0.0.0:23333/v1"
245 | )
246 | model_name = client.models.list().data[0].id
247 | model_name # 注册的模型名称需要被用于后续配置.
248 | ```
249 | 结果显示 `/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat/`, 接着,
250 | 创建配置脚本 `/root/opencompass/configs/models/hf_internlm/hf_internlm2_5_1_8b_chat_api.py`
251 |
252 | ```python
253 | from opencompass.models import OpenAI
254 |
255 | api_meta_template = dict(round=[
256 | dict(role='HUMAN', api_role='HUMAN'),
257 | dict(role='BOT', api_role='BOT', generate=True),
258 | ])
259 |
260 | models = [
261 | dict(
262 | abbr='InternLM-2.5-1.8B-Chat',
263 | type=OpenAI,
264 | path='/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat/', # 注册的模型名称
265 | key='sk-123456',
266 | openai_api_base='http://0.0.0.0:23333/v1/chat/completions',
267 | meta_template=api_meta_template,
268 | query_per_second=1,
269 | max_out_len=2048,
270 | max_seq_len=4096,
271 | batch_size=8),
272 | ]
273 | ```
274 |
275 | 然后运行
276 |
277 | ```bash
278 | opencompass --models hf_internlm2_5_1_8b_chat_api --datasets ceval_gen --debug # opencompass 命令基本等价于 python run.py 命令
279 | ```
280 |
281 | 得到结果:
282 |
283 | 
284 |
--------------------------------------------------------------------------------
/docs/L1/Evaluation/task.md:
--------------------------------------------------------------------------------
1 | # 评测 InternLM-1.8B 实践
2 |
3 | - 记录复现过程并截图。
4 |
5 | ## 基础任务(完成此任务即完成闯关)
6 |
7 | - 使用 OpenCompass 评测浦语 API 记录复现过程并截图。(注意:写博客提交作业时切记删除自己的 api_key!)
8 | - 使用 OpenCompass 评测 InternLM2.5-1.8B-Chat 模型在 ceval 数据集上的性能,记录复现过程并截图。(可选)
9 |
10 | ## 进阶任务(闯关不要求完成此任务)
11 |
12 | - 使用 OpenCompass 进行主观评测(选做)
13 | - 使用 OpenCompass 评测 InternLM2-Chat-1.8B 模型使用 LMDeploy部署后在 ceval 数据集上的性能(选做)
14 |
15 | ## 闯关材料提交(完成任务并且提交材料视为闯关成功)
16 |
17 | - 闯关作业总共分为一个任务,一个任务完成视作闯关成功。
18 | - 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 50 算力点奖励!!!
19 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
20 |
--------------------------------------------------------------------------------
/docs/L1/Evaluation/vlmevalkit.md:
--------------------------------------------------------------------------------
1 | # 多模态大模型评测实践
2 |
3 | VLMEvalKit (python 包名为 vlmeval) 是一款专为大型视觉语言模型 (Large Vision-Language Models, LVLMs) 评测而设计的开源工具包。该工具支持在各种基准测试上对大型视觉语言模型进行一键评估,无需进行繁重的数据准备工作,让评估过程更加简便。在 VLMEvalKit 中,我们对所有大型视觉语言模型生成的结果进行评测,并提供基于精确匹配与基于 LLM 的答案提取两种评测结果。
4 |
5 |
6 | ## 评测的基本步骤
7 |
8 | 在运行评测脚本之前,你需要先**配置** VLMs,并正确设置模型路径。然后你可以使用脚本 `run.py` 进行多个VLMs和基准测试的推理和评估。
9 |
10 |
11 | ### 第0步 安装和设置必要的密钥
12 |
13 | **安装**
14 |
15 | ```bash
16 | git clone https://github.com/open-compass/VLMEvalKit.git
17 | cd VLMEvalKit/
18 | pip install -e .
19 | pip install timm==1.0.11
20 | ```
21 |
22 | **设置密钥**
23 |
24 | 要使用 API 模型(如 GPT-4v, Gemini-Pro-V 等)进行推理,或使用 LLM API 作为**评判者或选择提取器**,你需要首先设置 API 密钥。如果你设置了密钥,VLMEvalKit 将默认使用一个评判 LLM 从输出中提取答案,否则它将使用**精确匹配模式**(在输出字符串中查找 "Yes", "No", "A", "B", "C"...)。**精确匹配模式只能应用于是或否任务和多项选择任务。**
25 |
26 |
27 | 你可以将所需的密钥放在 `$VLMEvalKit/.env` 中,或直接将它们设置为环境变量。如果你选择创建 `.env` 文件,
28 | VLMEvalKit 会根据你的环境变量配置来决定使用哪个模型作为评判 LLM.
29 |
30 |
31 | ### 第1步 配置
32 |
33 | **VLM 配置**:所有 VLMs 都在 `vlmeval/config.py` 中配置。对于某些 VLMs,在进行评估之前,你需要配置代码根目录(如 MiniGPT-4、PandaGPT 等)或模型权重根目录(如 LLaVA-v1-7B 等)。在评估时,你应该使用 `vlmeval/config.py` 中 `supported_VLM` 指定的模型名称来选择 VLM。
34 |
35 |
36 | ```python
37 | internvl_series = {
38 | 'InternVL-Chat-V1-1': partial(InternVLChat, model_path='OpenGVLab/InternVL-Chat-V1-1', version='V1.1'),
39 | 'InternVL-Chat-V1-2': partial(InternVLChat, model_path='OpenGVLab/InternVL-Chat-V1-2', version='V1.2'),
40 | 'InternVL-Chat-V1-2-Plus': partial(InternVLChat, model_path='OpenGVLab/InternVL-Chat-V1-2-Plus', version='V1.2'),
41 | 'InternVL-Chat-V1-5': partial(InternVLChat, model_path='OpenGVLab/InternVL-Chat-V1-5', version='V1.5'),
42 | 'Mini-InternVL-Chat-2B-V1-5': partial(InternVLChat, model_path='OpenGVLab/Mini-InternVL-Chat-2B-V1-5', version='V1.5'),
43 | 'Mini-InternVL-Chat-4B-V1-5': partial(InternVLChat, model_path='OpenGVLab/Mini-InternVL-Chat-4B-V1-5', version='V1.5'),
44 | # InternVL2 series
45 | 'InternVL2-1B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-1B', version='V2.0'),
46 | # 此处修改成等待评估模型的本地路径
47 | 'InternVL2-2B': partial(InternVLChat, model_path="/share/new_models/OpenGVLab/InternVL2-2B", version='V2.0'),
48 | 'InternVL2-4B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-4B', version='V2.0'),
49 | 'InternVL2-8B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-8B', version='V2.0'),
50 | 'InternVL2-26B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-26B', version='V2.0'),
51 | 'InternVL2-40B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-40B', version='V2.0', load_in_8bit=True),
52 | 'InternVL2-76B': partial(InternVLChat, model_path='OpenGVLab/InternVL2-Llama3-76B', version='V2.0'),
53 | }
54 | ```
55 |
56 | 此处我们指定好了等待评估模型 `InternVL2-2B` 的本地路径. 一些 VLMs 需要额外配置步骤, 例如 InstructBLIP 需要安装 LAVIS 库.
57 |
58 |
61 |
62 | ### 第2步 评测
63 |
64 | 我们使用 `run.py` 进行评估, 其参数如下:
65 |
66 | - `--data (list[str])`: 设置在 VLMEvalKit 中支持的数据集名称(在 `vlmeval/utils/dataset_config.py` 中定义)
67 | - `--model (list[str])`: 设置在 VLMEvalKit 中支持的 VLM 名称(在 `vlmeval/config.py` 中的 `supported_VLM` 中定义)
68 | - `--mode (str, 默认值为 'all', 可选值为 ['all', 'infer'])`:当 mode 设置为 "all" 时,将执行推理和评估;当设置为 "infer" 时,只执行推理
69 |
70 | - `--work-dir (str, default to '.')`: 存放测试结果的目录
71 |
72 |
73 |
74 |
75 | 你可以使用 `python` 或 `torchrun` 来运行脚本评测图像多模态评测集:
76 |
77 | ```bash
78 | # 使用 `python` 运行时,只实例化一个 VLM,并且它可能使用多个 GPU, 这推荐用于评估参数量非常大的 VLMs
79 | # 在 MMBench_DEV_EN、MME 和 SEEDBench_IMG 上使用 InternVL2-2B 进行推理和评估
80 | python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model InternVL2-2B --verbose
81 | # 在 MMBench_DEV_EN、MME 和 SEEDBench_IMG 上使用 InternVL2-2B 仅进行推理
82 | python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model InternVL2-2B --verbose --mode infer
83 |
84 | # 使用 `torchrun` 运行时稍有不同,每个 GPU 上实例化一个 VLM 实例, 这可以加快推理速度. 但是,这仅适用于消耗少量 GPU 内存的 VLMs。
85 | ```
86 |
87 | 评估结果将作为日志打印出来。此外,结果文件也会在目录 `$YOUR_WORKING_DIRECTORY/{model_name}` 中生成。以 `.csv` 结尾的文件包含评估的指标。
88 |
89 | ## 部署本地语言模型作为评判LLM
90 |
91 | 上述默认设置使用 OpenAI 的 GPT 作为评判 LLM。你也可以使用 [LMDeploy](https://github.com/InternLM/lmdeploy) 部署本地评判 LLM。
92 |
93 | 首先进行安装:
94 | ```bash
95 | pip install lmdeploy==0.6.1 openai==1.52.0
96 | ```
97 |
98 | 假设我们使用 internlm2_5-1_8b-chat 作为评判,端口为 23333,密钥为 sk-123456(在这个本地部署的场景中,OPENAI_API_KEY 可以随意设置,只要遵循指定的格式), 然后可以通过一行代码部署本地评判 LLM:
99 |
100 | ```bash
101 | # --cache-max-entry-count 0.4 设置用于减少 GPU 占用
102 | lmdeploy serve api_server /share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat/ --cache-max-entry-count 0.4 --server-port 23333
103 | ```
104 |
105 | 
106 |
107 |
108 | 新打开一个终端, 使用以下 Python 代码获取由 LMDeploy 注册的模型名称:
109 | ```python
110 | from openai import OpenAI
111 | client = OpenAI(
112 | api_key='sk-123456',
113 | base_url="http://0.0.0.0:23333/v1"
114 | )
115 | model_name = client.models.list().data[0].id
116 | model_name
117 | ```
118 | 显示结果为 `/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat`, 接着配置对应环境变量,以告诉 VLMEvalKit 如何使用本地评判 LLM。正如上面提到的,也可以在 `$VLMEvalKit/.env` 文件中设置:
119 |
120 | ```
121 | OPENAI_API_KEY=sk-123456
122 | OPENAI_API_BASE=http://0.0.0.0:23333/v1/chat/completions
123 | LOCAL_LLM='/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat' # 注册的模型名称
124 | ```
125 |
126 | 最后,你可以运行第2步中的命令,使用本地评判 LLM 来评估你的 VLM, 例如:
127 |
128 | ```bash
129 | python run.py --data MMBench_DEV_EN MME SEEDBench_IMG --model InternVL2-2B --verbose
130 | ```
131 | 
132 |
133 |
--------------------------------------------------------------------------------
/docs/L1/InternIntro/README.md:
--------------------------------------------------------------------------------
1 | # 玩转书生「多模态对话」与「AI搜索」产品
2 | 
3 | Hi, 大家好~ 本节课程会带大家体验书生系列的大模型产品,让我们跟着书生的足迹一起探索生成式AI的世界吧!
4 |
5 | > 目前,书生系列下的所有产品均免费向所有社区用户提供服务:无会员、无广告、高性能部署!我们希望让所有对大模型技术、应用、开发工具链感兴趣的小伙伴第一时间体验到相应的功能。
6 | >
7 |
8 | # 1. 书生产品矩阵
9 |
10 | - [**书生·浦语**](https://internlm-chat.intern-ai.org.cn/):基于原生的 InternLM2.5 最新 Chat 模型 (InternLM2.5-20B) 搭建聊天机器人应用。所有注册用户默认开放 3 百万 Tokens/月的 API 调用额度!
11 |
12 | 
13 |
14 | - [**MindSearch**](https://internlm-chat.intern-ai.org.cn/suggestion/oVmlpR34V9U6v9KBQ1TN7IpPQh1Z89ONciSGUKmgFFA=):InternLM 组织今年开源的 AI 搜索引擎 (框架),基于多智能体技术将你提出的问题进行分析、拆解、网页搜索,最终给出有参考依据的高可信度回答。目前可直接在**书生·浦语**产品内体验以 InternLM2.5-20B 为 Agent 的 MindSearch 官方实现。
15 |
16 | 
17 |
18 | - [**书生·万象**](https://internvl.opengvlab.com/):InternVL 开源模型的官方产品,原生支持图文多模态对话能力。
19 |
20 | # 2. 书生·浦语
21 |
22 | ## (1) 对话
23 |
24 | 相信参与课程的同学都对这类产品非常熟悉了,与所有大语言模型产品相同。你可以与浦语进行以,”代码编程、文章创作、灵感创意、角色扮演、语言翻译、逻辑推理等等”任意主题的对话。也可在对话内尝试 prompt enginering 让浦语完成更复杂任务。
25 |
26 | 
27 |
28 | ## (2) 调用 API
29 |
30 | 在左侧导航栏点击“更多”即可进入 [API 控制台](https://internlm.intern-ai.org.cn/api/document)
31 |
32 | 
33 |
34 | API 控制台内包含 “API 文档”、“API Tokens”、“限流策略”、“调用明细” 4 个模块。下面,我们将以首次调用浦语 Chat API 的用户视角了解这 4 个模块的功能。
35 |
36 | 
37 |
38 | ### API 文档
39 |
40 | [API 文档](https://internlm.intern-ai.org.cn/api/document)中给出了
41 |
42 | - API URL
43 | - API Auth
44 | - Python、Curl、openai 库的调用示例
45 | - 请求参数、返回参数说明
46 |
47 | 等等快速开始使用浦语 API 的说明。更重要的是,浦语 API 已经**支持 Tool Call (Beta) 功能**啦!所有字段与 OpenAI 对齐,让使用 ChatGPT API 格式的同学可以无缝切换到浦语 API。
48 |
49 | 
50 |
51 | 以下是使用 `curl` 工具非流式调用浦语 API 的一段示例代码:
52 |
53 | ```bash
54 | curl --location 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1/chat/completions' \
55 | --header 'Authorization: Bearer xxxxxxx' \
56 | --header 'Content-Type: application/json' \
57 | --data '{
58 | "model": "internlm2.5-latest",
59 | "messages": [{
60 | "role": "user",
61 | "content": "你知道刘慈欣吗?"
62 | }, {
63 | "role": "assistant",
64 | "content": "为一个人工智能助手,我知道刘慈欣。他是一位著名的中国科幻小说家和工程师,曾经获得过多项奖项,包括雨果奖、星云奖等。"
65 | },{
66 | "role": "user",
67 | "content": "他什么作品得过雨果奖?"
68 | }],
69 | "temperature": 0.8,
70 | "top_p": 0.9
71 | }'
72 | ```
73 |
74 | ### 获取 API Tokens
75 |
76 | 从上面的代码可以看到,调用浦语 API 时需要在请求 Header 内传入 Authorization Tokens (`Authorization: Bearer xxxxxxx`) 参数用于用户身份验证。我们需要在 [API Tokens 模块](https://internlm.intern-ai.org.cn/api/tokens)内创建此 API Tokens 替换掉 `xxxxxxx` 。
77 |
78 | 
79 |
80 | 
81 |
82 | 
83 |
84 | 注意在最后一步时不要着急点确认,先复制好 tokens 妥善保管到自己的文件或者权限管理服务中。**点击确认后将不再显示此 Token。**
85 |
86 | ### 查看 API 可用 Models
87 |
88 | 如图所示,目前 Chat API 仅支持以 `internlm2.5-latest` 作为 model ID,它将默认指向我们最新的 InternLM2.5 模型 `internlm2.5-20b-0719` 。
89 |
90 | **注意**:我们可能会定期上线一些新版的模型,或者改变 `internlm2.5-latest` 模型指向的实际模型版本。可以通过 Model API 查询当前可用的模型 ID。
91 |
92 | | 模型 | 描述 | 窗口长度 | 最大输出 Tokens |
93 | | --- | --- | --- | --- |
94 | | internlm2.5-latest | 默认指向我们最新发布的 internlm2.5 系列模型,当前指向`internlm2.5-20b-0719` | 32K | 4,096 tokens |
95 |
96 | 
97 |
98 | ### 查看 API Usage 与 API Rate Limits
99 |
100 | 我们为所有社区新注册的用户提供了 1 百万 Input Tokens/月,3 百万 Output Tokens/月 的**免费调用额度**!可在 [API Usage 模块](https://internlm.intern-ai.org.cn/api/callDetail)查看到本月已用 Tokens 的数量,以及请求次数、请求 Tokens 的历史调用曲线。
101 |
102 | 
103 |
104 | 在 [API 限流策略](https://internlm.intern-ai.org.cn/api/strategy)模块可以查询到我们对这个账户调用 API 频率的流控限制,所有新注册的社区用户默认值为:
105 |
106 | - RPM (Requests per Minute):10
107 | - TPM (Tokens per Minute):5000
108 |
109 | **注意**:实战营的同学们,最好不要使用下图中的“申请更高流控配置”来申请 API 的限流策略。这功能一般是开放给企业用户,审核非常严格!!!可以参考下面一节的三个渠道来提高 RPM, TPM 以及 Tokens。
110 |
111 | 
112 |
113 | ### 如何获取更多模型 Tokens,提升 RPM/TPM
114 |
115 | 总的来说我们提供了 3 个渠道让实战营的同学获取 tokens 并提高限流策略:
116 |
117 | - **实战营闯关**:比如,通过入门课程的《Python 基础知识》闯关
118 | - **申请项目**:完成项目等级和初版GitHub Repo和技术架构图
119 | - **共学计划邀请同学**:邀请 6 位同学以上参加书生大模型实战营
120 |
121 | 详细获取方式可查看[《闯关手册》](https://aicarrier.feishu.cn/wiki/QtJnweAW1iFl8LkoMKGcsUS9nld)~
122 |
123 | # 3. MindSearch
124 |
125 | [MindSearch](https://internlm-chat.intern-ai.org.cn/suggestion/oVmlpR34V9U6v9KBQ1TN7IpPQh1Z89ONciSGUKmgFFA=) 是一个开源的 AI 搜索引擎。它会对你提出的问题进行分析并拆解为数个子问题,在互联网上搜索、总结得到各个子问题的答案,最后通过模型总结得到最终答案。书生·浦语上的智能体为 MindSearch 的官方实现 (基于 InternLM2.5-20B) 具有与 [Perplexity.ai](http://perplexity.ai/) Pro 相当的性能。
126 |
127 | ## (1) 拆解问题
128 |
129 | 以“**请分析一下 2024 年诺贝尔物理学奖为何会颁发给人工智能领域的科学家 Geoffrey E. Hinton,这一举动对这两个领域的从业人员会有什么影响?**”问题为例,在主节点中模型将此问题拆解为了:
130 |
131 | - **2024年诺贝尔物理学奖为何颁发给Geoffrey E. Hinton?**
132 | - **2024年诺贝尔物理学奖颁发给Geoffrey E. Hinton对物理学和人工智能领域从业人员的影响是什么?**
133 |
134 | 两个子问题 (如下图)
135 |
136 | 
137 |
138 | ## (2) 解决子问题
139 |
140 | 解决子问题的步骤分为以下 3 步:
141 |
142 | - **思考**:我需要在互联网上搜索什么资料来回答这个问题?子节点总结搜索关键词调用搜索引擎搜索到海量参考网页。
143 | - **信息来源**:根据首次搜索到的网页摘要,子节点决定知否对网页进行全文精读。
144 | - **信息整合**:整合精读网页的所有信息形成子节点的结论。
145 |
146 | 
147 |
148 | 
149 |
150 | ## (3) 总结子节点结论
151 |
152 | 一般情况下主节点会根据子节点得出的结论,总结形成最终回复
153 |
154 | 
155 |
156 | 部分情况下,主节点会根据子节点得到的结论进一步拆解子问题回到步骤 (1) 直到得到最终结论。
157 |
--------------------------------------------------------------------------------
/docs/L1/InternIntro/tasks.md:
--------------------------------------------------------------------------------
1 | # 玩转书生「多模态对话」与「AI搜索」产品 - 任务
2 |
3 | # **基础任务 (完成此任务即完成闯关)**
4 |
5 | | 相关产品 | 任务描述 |
6 | | --- | --- |
7 | | [MindSearch](https://internlm-chat.intern-ai.org.cn/suggestion/oVmlpR34V9U6v9KBQ1TN7IpPQh1Z89ONciSGUKmgFFA=)
开源的 AI 搜索引擎 |使用 MindSearch 在以下三个问题中选择一个你感兴趣的进行提问
1. 目前生成式AI在学术和工业界有什么最新进展?
2. 2024 年诺贝尔物理学奖为何会颁发给人工智能领域的科学家 Geoffrey E. Hinton,这一举动对这两个领域的从业人员会有什么影响?
3. 最近大火的中国 3A 大作《黑神话·悟空》里有什么让你难忘的精彩故事情节?
**任务要求**:将模型回复截图保存提交到飞书问卷。|
8 | |[书生·浦语](https://internlm-chat.intern-ai.org.cn/)
InternLM 开源模型官方的对话类产品 | 选择逻代码编程、文章创作、灵感创意、角色扮演、语言翻译、逻辑推理以上任意一个场景或者你自己感兴趣的话题与浦语进行对话 (轮次不限)。
**任务要求**:截图保存对话内容并提交到飞书问卷。 |
9 | |[书生·万象](https://internvl.opengvlab.com/)
InternVL 开源的视觉语言模型官方的对话产品 | 体验书生·万象模型多模态能力,从图片 OCR、图片内容理解等方面与书生·万象展开一次包含图片内容的对话
**任务要求**:截图保存对话内容并提交到飞书问卷。 |
10 | # 进阶任务 (优秀学员需要完成)
11 |
12 | - MindSearch 话题挑战
13 |
14 | 浦语小助手将基础任务中的三个问题在知乎上进行了提问。
15 |
16 | 1. [目前生成式AI在学术和工业界有什么最新进展?](https://www.zhihu.com/question/1841339763)
17 | 2. [2024 年诺贝尔物理学奖为何会颁发给人工智能领域,这一举动对这两个领域的从业人员会有什么影响?](https://www.zhihu.com/question/1915470960)
18 | 3. [最近大火的中国 3A 大作《黑神话·悟空》里有什么让你难忘的精彩故事情节?](https://www.zhihu.com/question/1915582405)
19 |
20 | 请以 MindSearch 的回复作为参考 (推荐) 或者直接粘贴 MindSearch 的回复内容在知乎上回答 3 个问题的任意一个。
21 |
22 | - 达标要求
23 | 1. 注明回答中使用了 AI 搜索引擎 MindSearch (任何方式注明均可,比如“以下答案参考 AI 搜索引擎 [MindSearch](需附带链接)”)
24 | 2. 将你在知乎回复的答案链接提交到飞书问卷
25 |
26 | # **闯关材料提交 (完成材料提交视为闯关成功)**
27 |
28 | - 闯关任务分为基础任务和进阶任务,完成基础任务即视为闯关成功。完成进阶任务助教批改通过后即获得 50 算力点奖励!
29 | - **作业笔记**:将作业笔记以飞书文档、知乎、CSDN的等任一社交媒体形式记录,并将文档链接提交到以下问卷,助教老师批改后将获得 50 算力点奖励!!!
30 | - 提交地址:[https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd](https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd)
31 |
32 |
--------------------------------------------------------------------------------
/docs/L1/LlamaIndex/readme.md:
--------------------------------------------------------------------------------
1 | # LlamaIndex+InternLM RAG 实践
2 |
3 |
4 |
5 | Hello大家好,迎来到实战营第四期的llamaindex+InternLM RAG课程,本文将分为以下几个部分来介绍,如何使用 LlamaIndex+InternLM 构建 RAG 知识库(以 InternStudio 的环境为例)
6 |
7 | - 前置知识
8 | - 浦语API+LlamaIndex实践案例
9 | - 本地部署InternLM+LlamaIndex实践案例
10 | - 闯关任务
11 |
12 | ## 1. 前置知识
13 |
14 | 正式介绍检索增强生成(Retrieval Augmented Generation,RAG)技术以前,大家不妨想想为什么会出现这样一个技术。
15 | 给模型注入新知识的方式,可以简单分为两种方式,一种是内部的,即更新模型的权重,另一个就是外部的方式,给模型注入格外的上下文或者说外部信息,不改变它的的权重。
16 | 第一种方式,改变了模型的权重即进行模型训练,这是一件代价比较大的事情,大语言模型具体的训练过程,可以参考[InternLM2技术报告](https://arxiv.org/abs/2403.17297)。
17 | 第二种方式,并不改变模型的权重,只是给模型引入格外的信息。类比人类编程的过程,第一种方式相当于你记住了某个函数的用法,第二种方式相当于你阅读函数文档然后短暂的记住了某个函数的用法。
18 |
19 | 
20 |
21 | 对比两种注入知识方式,第二种更容易实现。RAG 正是这种方式。它能够让基础模型实现非参数知识更新,无需训练就可以掌握新领域的知识。本次课程选用了 LlamaIndex 框架。LlamaIndex 是一个上下文增强的 LLM 框架,旨在通过将其与特定上下文数据集集成,增强大型语言模型(LLMs)的能力。它允许您构建应用程序,既利用 LLMs 的优势,又融入您的私有或领域特定信息。
22 |
23 | ### RAG 效果比对
24 |
25 | 如图所示,由于`xtuner`是一款比较新的框架, `InternLM2-Chat-1.8B` 训练数据库中并没有收录到它的相关信息。左图中问答均未给出准确的答案。右图未对 `InternLM2-Chat-1.8B` 进行任何增训的情况下,通过 RAG 技术实现的新增知识问答。
26 |
27 | 
28 |
29 | ## 2. 浦语 API+LlamaIndex 实践
30 |
31 | [传送门](./readme_api.md)
32 |
33 | ## 3. 本地部署InternLM+LlamaIndex实践
34 |
35 | [传送门](./readme_local.md)
36 |
37 |
38 | ## 4. 作业
39 |
40 | 作业请访问[作业](./task.md)。
41 |
--------------------------------------------------------------------------------
/docs/L1/LlamaIndex/readme_api.md:
--------------------------------------------------------------------------------
1 |
2 | # LlamaIndex+InternLM API 实践
3 |
4 |
5 | 本文将分为以下几个部分来介绍
6 |
7 | - 前置知识
8 | - 环境、模型准备
9 | - 是否使用 LlamaIndex 前后对比
10 | - LlamaIndex Web
11 |
12 |
13 | ## 1. 前置知识
14 |
15 | 正式介绍检索增强生成(Retrieval Augmented Generation,RAG)技术以前,大家不妨想想为什么会出现这样一个技术。
16 | 给模型注入新知识的方式,可以简单分为两种方式,一种是内部的,即更新模型的权重,另一个就是外部的方式,给模型注入格外的上下文或者说外部信息,不改变它的的权重。
17 | 第一种方式,改变了模型的权重即进行模型训练,这是一件代价比较大的事情,大语言模型具体的训练过程,可以参考[InternLM2](https://arxiv.org/abs/2403.17297)技术报告。第二种方式,并不改变模型的权重,只是给模型引入格外的信息。类比人类编程的过程,第一种方式相当于你记住了某个函数的用法,第二种方式相当于你阅读函数文档然后短暂的记住了某个函数的用法。
18 |
19 | 
20 |
21 | 对比两种注入知识方式,第二种更容易实现。RAG正是这种方式。它能够让基础模型实现非参数知识更新,无需训练就可以掌握新领域的知识。本次课程选用了LlamaIndex框架。LlamaIndex 是一个上下文增强的 LLM 框架,旨在通过将其与特定上下文数据集集成,增强大型语言模型(LLMs)的能力。它允许您构建应用程序,既利用 LLMs 的优势,又融入您的私有或领域特定信息。
22 |
23 | ### RAG 效果比对
24 |
25 | 如图所示,由于`xtuner`是一款比较新的框架, `浦语 API ` 训练数据库中并没有收录到它的相关信息。左图中问答均未给出准确的答案。右图未对 `浦语 API ` 进行任何增训的情况下,通过 RAG 技术实现的新增知识问答。
26 |
27 | 
28 |
29 | ## 2. 环境、模型准备
30 |
31 | ### 2.1 配置基础环境
32 | 这里以在 [Intern Studio](https://studio.intern-ai.org.cn/) 服务器上部署LlamaIndex为例。
33 |
34 |
35 | 首先,打开 `Intern Studio` 界面,点击 **创建开发机** 配置开发机系统。
36 | 
37 |
38 | 填写 `开发机名称` 后,点击 选择镜像 使用 `Cuda12.0-conda` 镜像,然后在资源配置中,使用 `30% A100 * 1` 的选项,然后立即创建开发机器。
39 | 
40 |
41 | 点击 `进入开发机` 选项。
42 | 
43 |
44 | 进入开发机后,创建新的conda环境,命名为 `llamaindex`,在命令行模式下运行:
45 | ```bash
46 | conda create -n llamaindex python=3.10
47 | ```
48 | 复制完成后,在本地查看环境。
49 | ```bash
50 | conda env list
51 | ```
52 | 结果如下所示。
53 | ```bash
54 | # conda environments:
55 | #
56 | base * /root/.conda
57 | llamaindex /root/.conda/envs/llamaindex
58 | ```
59 |
60 | 运行 `conda` 命令,激活 `llamaindex` 然后安装相关基础依赖
61 | **python** 虚拟环境:
62 | ```bash
63 | conda activate llamaindex
64 | ```
65 | **安装python 依赖包**
66 | ```bash
67 | pip install einops==0.7.0 protobuf==5.26.1
68 | ```
69 |
70 | 环境激活后,命令行左边会显示当前(也就是 `llamaindex` )的环境名称,如下图所示:
71 | 
72 |
73 | ### 2.2 安装 Llamaindex
74 | 安装 Llamaindex和相关的包
75 | ```bash
76 | conda activate llamaindex
77 | pip install llama-index==0.11.20
78 | pip install llama-index-llms-replicate==0.3.0
79 | pip install llama-index-llms-openai-like==0.2.0
80 | pip install llama-index-embeddings-huggingface==0.3.1
81 | pip install llama-index-embeddings-instructor==0.2.1
82 | pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 --index-url https://download.pytorch.org/whl/cu121
83 | ```
84 |
85 | ### 2.3 下载 Sentence Transformer 模型
86 |
87 | 源词向量模型 [Sentence Transformer](https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2):(我们也可以选用别的开源词向量模型来进行 Embedding,目前选用这个模型是相对轻量、支持中文且效果较好的,同学们可以自由尝试别的开源词向量模型)
88 | 运行以下指令,新建一个python文件
89 | ```bash
90 | cd ~
91 | mkdir llamaindex_demo
92 | mkdir model
93 | cd ~/llamaindex_demo
94 | touch download_hf.py
95 | ```
96 | 打开`download_hf.py` 贴入以下代码
97 | ```bash
98 | import os
99 |
100 | # 设置环境变量
101 | os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
102 |
103 | # 下载模型
104 | os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/model/sentence-transformer')
105 | ```
106 |
107 | 然后,在 /root/llamaindex_demo 目录下执行该脚本即可自动开始下载:
108 | ```bash
109 | cd /root/llamaindex_demo
110 | conda activate llamaindex
111 | python download_hf.py
112 | ```
113 | 更多关于镜像使用可以移步至 [HF Mirror](https://hf-mirror.com/) 查看。
114 |
115 |
116 | `推荐用户从modelscope下载 `
117 |
118 | https://modelscope.cn/models/Ceceliachenen/paraphrase-multilingual-MiniLM-L12-v2/summary
119 |
120 | ```
121 | git lfs install
122 |
123 | cd /root/model/
124 |
125 | git clone https://www.modelscope.cn/Ceceliachenen/paraphrase-multilingual-MiniLM-L12-v2.git
126 |
127 | mv paraphrase-multilingual-MiniLM-L12-v2 sentence-transformer
128 | ```
129 |
130 |
131 | ### 2.4 下载 NLTK 相关资源
132 | 我们在使用开源词向量模型构建开源词向量的时候,需要用到第三方库 `nltk` 的一些资源。正常情况下,其会自动从互联网上下载,但可能由于网络原因会导致下载中断,此处我们可以从国内仓库镜像地址下载相关资源,保存到服务器上。
133 | 我们用以下命令下载 nltk 资源并解压到服务器上:
134 | ```bash
135 | cd /root
136 | git clone https://gitee.com/yzy0612/nltk_data.git --branch gh-pages
137 | cd nltk_data
138 | mv packages/* ./
139 | cd tokenizers
140 | unzip punkt.zip
141 | cd ../taggers
142 | unzip averaged_perceptron_tagger.zip
143 | ```
144 | 之后使用时服务器即会自动使用已有资源,无需再次下载
145 |
146 | ## 3. 是否使用 LlamaIndex 前后对比
147 |
148 | ### 3.1 不使用 LlamaIndex RAG(仅API)
149 |
150 | 浦语官网和硅基流动都提供了InternLM的类OpenAI接口格式的免费的 API,可以访问以下两个了解两个 API 的使用方法和 Key。
151 |
152 | 浦语官方 API:https://internlm.intern-ai.org.cn/api/document
153 | 硅基流动:https://cloud.siliconflow.cn/models?mfs=internlm
154 |
155 |
156 | 运行以下指令,新建一个python文件
157 | ```bash
158 | cd ~/llamaindex_demo
159 | touch test_internlm.py
160 | ```
161 |
162 | 打开test_internlm.py 贴入以下代码
163 | ```python
164 | from openai import OpenAI
165 |
166 | base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
167 | api_key = "sk-请填写准确的 token!"
168 | model="internlm2.5-latest"
169 |
170 | # base_url = "https://api.siliconflow.cn/v1"
171 | # api_key = "sk-请填写准确的 token!"
172 | # model="internlm/internlm2_5-7b-chat"
173 |
174 | client = OpenAI(
175 | api_key=api_key ,
176 | base_url=base_url,
177 | )
178 |
179 | chat_rsp = client.chat.completions.create(
180 | model=model,
181 | messages=[{"role": "user", "content": "xtuner是什么?"}],
182 | )
183 |
184 | for choice in chat_rsp.choices:
185 | print(choice.message.content)
186 | ```
187 | 之后运行
188 | ```bash
189 | conda activate llamaindex
190 | cd ~/llamaindex_demo/
191 | python test_internlm.py
192 | ```
193 | 结果为:
194 |
195 | 
196 |
197 | 回答的效果并不好,并不是我们想要的xtuner。
198 |
199 | ### 3.2 使用 API+LlamaIndex
200 |
201 | ```bash
202 | conda activate llamaindex
203 | ```
204 | 运行以下命令,获取知识库
205 | ```bash
206 | cd ~/llamaindex_demo
207 | mkdir data
208 | cd data
209 | git clone https://github.com/InternLM/xtuner.git
210 | mv xtuner/README_zh-CN.md ./
211 | ```
212 | 运行以下指令,新建一个python文件
213 | ```bash
214 | cd ~/llamaindex_demo
215 | touch llamaindex_RAG.py
216 | ```
217 | 打开`llamaindex_RAG.py`贴入以下代码
218 | ```python
219 | import os
220 | os.environ['NLTK_DATA'] = '/root/nltk_data'
221 |
222 | from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
223 | from llama_index.core.settings import Settings
224 | from llama_index.embeddings.huggingface import HuggingFaceEmbedding
225 | from llama_index.legacy.callbacks import CallbackManager
226 | from llama_index.llms.openai_like import OpenAILike
227 |
228 |
229 | # Create an instance of CallbackManager
230 | callback_manager = CallbackManager()
231 |
232 | api_base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
233 | model = "internlm2.5-latest"
234 | api_key = "请填写 API Key"
235 |
236 | # api_base_url = "https://api.siliconflow.cn/v1"
237 | # model = "internlm/internlm2_5-7b-chat"
238 | # api_key = "请填写 API Key"
239 |
240 |
241 |
242 | llm =OpenAILike(model=model, api_base=api_base_url, api_key=api_key, is_chat_model=True,callback_manager=callback_manager)
243 |
244 |
245 | #初始化一个HuggingFaceEmbedding对象,用于将文本转换为向量表示
246 | embed_model = HuggingFaceEmbedding(
247 | #指定了一个预训练的sentence-transformer模型的路径
248 | model_name="/root/model/sentence-transformer"
249 | )
250 | #将创建的嵌入模型赋值给全局设置的embed_model属性,
251 | #这样在后续的索引构建过程中就会使用这个模型。
252 | Settings.embed_model = embed_model
253 |
254 | #初始化llm
255 | Settings.llm = llm
256 |
257 | #从指定目录读取所有文档,并加载数据到内存中
258 | documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
259 | #创建一个VectorStoreIndex,并使用之前加载的文档来构建索引。
260 | # 此索引将文档转换为向量,并存储这些向量以便于快速检索。
261 | index = VectorStoreIndex.from_documents(documents)
262 | # 创建一个查询引擎,这个引擎可以接收查询并返回相关文档的响应。
263 | query_engine = index.as_query_engine()
264 | response = query_engine.query("xtuner是什么?")
265 |
266 | print(response)
267 | ```
268 | 之后运行
269 |
270 | ```bash
271 | conda activate llamaindex
272 | cd ~/llamaindex_demo/
273 | python llamaindex_RAG.py
274 | ```
275 |
276 | 注意:第一次运行会下载相关数据需要一段时间,请耐心等待,如中断可能导致第二次运行因为文件损坏报错!!!
277 |
278 | 结果为:
279 |
280 |
281 |
282 | 借助RAG技术后,就能获得我们想要的答案了。
283 |
284 | ## 4. LlamaIndex web
285 | 运行之前首先安装依赖
286 |
287 | ```shell
288 | pip install streamlit==1.39.0
289 | ```
290 |
291 | 运行以下指令,新建一个python文件
292 |
293 | ```bash
294 | cd ~/llamaindex_demo
295 | touch app.py
296 | ```
297 |
298 | 打开`app.py`贴入以下代码
299 | ```python
300 | import streamlit as st
301 | from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
302 | from llama_index.embeddings.huggingface import HuggingFaceEmbedding
303 | from llama_index.legacy.callbacks import CallbackManager
304 | from llama_index.llms.openai_like import OpenAILike
305 |
306 | # Create an instance of CallbackManager
307 | callback_manager = CallbackManager()
308 |
309 | api_base_url = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/"
310 | model = "internlm2.5-latest"
311 | api_key = "请填写 API Key"
312 |
313 | # api_base_url = "https://api.siliconflow.cn/v1"
314 | # model = "internlm/internlm2_5-7b-chat"
315 | # api_key = "请填写 API Key"
316 |
317 | llm =OpenAILike(model=model, api_base=api_base_url, api_key=api_key, is_chat_model=True,callback_manager=callback_manager)
318 |
319 |
320 |
321 | st.set_page_config(page_title="llama_index_demo", page_icon="🦜🔗")
322 | st.title("llama_index_demo")
323 |
324 | # 初始化模型
325 | @st.cache_resource
326 | def init_models():
327 | embed_model = HuggingFaceEmbedding(
328 | model_name="/root/model/sentence-transformer"
329 | )
330 | Settings.embed_model = embed_model
331 |
332 | #用初始化llm
333 | Settings.llm = llm
334 |
335 | documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
336 | index = VectorStoreIndex.from_documents(documents)
337 | query_engine = index.as_query_engine()
338 |
339 | return query_engine
340 |
341 | # 检查是否需要初始化模型
342 | if 'query_engine' not in st.session_state:
343 | st.session_state['query_engine'] = init_models()
344 |
345 | def greet2(question):
346 | response = st.session_state['query_engine'].query(question)
347 | return response
348 |
349 |
350 | # Store LLM generated responses
351 | if "messages" not in st.session_state.keys():
352 | st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
353 |
354 | # Display or clear chat messages
355 | for message in st.session_state.messages:
356 | with st.chat_message(message["role"]):
357 | st.write(message["content"])
358 |
359 | def clear_chat_history():
360 | st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
361 |
362 | st.sidebar.button('Clear Chat History', on_click=clear_chat_history)
363 |
364 | # Function for generating LLaMA2 response
365 | def generate_llama_index_response(prompt_input):
366 | return greet2(prompt_input)
367 |
368 | # User-provided prompt
369 | if prompt := st.chat_input():
370 | st.session_state.messages.append({"role": "user", "content": prompt})
371 | with st.chat_message("user"):
372 | st.write(prompt)
373 |
374 | # Gegenerate_llama_index_response last message is not from assistant
375 | if st.session_state.messages[-1]["role"] != "assistant":
376 | with st.chat_message("assistant"):
377 | with st.spinner("Thinking..."):
378 | response = generate_llama_index_response(prompt)
379 | placeholder = st.empty()
380 | placeholder.markdown(response)
381 | message = {"role": "assistant", "content": response}
382 | st.session_state.messages.append(message)
383 | ```
384 |
385 | 之后运行
386 | ```bash
387 | streamlit run app.py
388 | ```
389 |
390 | 然后在命令行点击,红框里的url。
391 |
392 | 
393 |
394 |
395 | 即可进入以下网页,然后就可以开始尝试问问题了。
396 |
397 | 
398 |
399 |
400 | 询问结果为:
401 |
402 | 
403 |
404 |
405 | ## 5. 小结
406 | 恭喜你,成功通关本关卡!继续加油!你成功使用 LlamaIndex 运行了浦语API,并实现了知识库的构建与检索。这为管理和利用大规模知识库提供了强大的工具和方法。接下来,可以进一步优化和扩展功能,以满足更复杂的需求。
407 |
408 | ## 6. 作业
409 | 作业请访问[作业](./task.md)。
410 |
--------------------------------------------------------------------------------
/docs/L1/LlamaIndex/readme_local.md:
--------------------------------------------------------------------------------
1 | # LlamaIndex+本地部署InternLM实践
2 |
3 |
4 |
5 | Hello大家好,迎来到实战营第四期的llamaindex+Internlm2 RAG课程,本文将分为以下几个部分来介绍,如何使用 LlamaIndex 来部署 InternLM2 1.8B并测试(以 InternStudio 的环境为例)
6 |
7 | - 前置知识
8 | - 环境、模型准备
9 | - LlamaIndex HuggingFaceLLM
10 | - LlamaIndex RAG
11 |
12 | ## 1. 前置知识
13 |
14 | 正式介绍检索增强生成(Retrieval Augmented Generation,RAG)技术以前,大家不妨想想为什么会出现这样一个技术。
15 | 给模型注入新知识的方式,可以简单分为两种方式,一种是内部的,即更新模型的权重,另一个就是外部的方式,给模型注入格外的上下文或者说外部信息,不改变它的的权重。
16 | 第一种方式,改变了模型的权重即进行模型训练,这是一件代价比较大的事情,大语言模型具体的训练过程,可以参考[InternLM2技术报告](https://arxiv.org/abs/2403.17297)。
17 | 第二种方式,并不改变模型的权重,只是给模型引入格外的信息。类比人类编程的过程,第一种方式相当于你记住了某个函数的用法,第二种方式相当于你阅读函数文档然后短暂的记住了某个函数的用法。
18 |
19 | 
20 |
21 | 对比两种注入知识方式,第二种更容易实现。RAG 正是这种方式。它能够让基础模型实现非参数知识更新,无需训练就可以掌握新领域的知识。本次课程选用了 LlamaIndex 框架。LlamaIndex 是一个上下文增强的 LLM 框架,旨在通过将其与特定上下文数据集集成,增强大型语言模型(LLMs)的能力。它允许您构建应用程序,既利用 LLMs 的优势,又融入您的私有或领域特定信息。
22 |
23 | ### RAG 效果比对
24 |
25 | 如图所示,由于`xtuner`是一款比较新的框架, `InternLM2-Chat-1.8B` 训练数据库中并没有收录到它的相关信息。左图中问答均未给出准确的答案。右图未对 `InternLM2-Chat-1.8B` 进行任何增训的情况下,通过 RAG 技术实现的新增知识问答。
26 |
27 | 
28 |
29 | ## 2. 环境、模型准备
30 |
31 | ### 2.1 配置基础环境
32 |
33 | 这里以在 [Intern Studio](https://studio.intern-ai.org.cn/) 服务器上部署 LlamaIndex 为例。
34 |
35 | 首先,打开 `Intern Studio` 界面,点击 **创建开发机** 配置开发机系统。
36 |
37 | 
38 |
39 | 填写 `开发机名称` 后,点击 选择镜像 使用 `Cuda11.7-conda` 镜像,然后在资源配置中,使用 `30% A100 * 1` 的选项,然后立即创建开发机器。
40 |
41 | 
42 |
43 | 点击 `进入开发机` 选项。
44 |
45 | 
46 |
47 | 进入开发机后,创建新的 conda 环境,命名为 `llamaindex`,在命令行模式下运行:
48 |
49 | ```bash
50 | conda create -n llamaindex python=3.10
51 | ```
52 |
53 | 复制完成后,在本地查看环境。
54 |
55 | ```bash
56 | conda env list
57 | ```
58 |
59 | 结果如下所示。
60 |
61 | ```bash
62 | # conda environments:
63 | #
64 | base * /root/.conda
65 | llamaindex /root/.conda/envs/llamaindex
66 | ```
67 |
68 | 运行 `conda` 命令,激活 `llamaindex` :
69 |
70 | ```bash
71 | conda activate llamaindex
72 | ```
73 |
74 | 环境激活后,命令行左边会显示当前(也就是 `llamaindex` )的环境名称,如下图所示:
75 |
76 | 
77 |
78 | 然后**安装 python 相关基础依赖包**:
79 |
80 | ```bash
81 | pip install einops==0.7.0 protobuf==5.26.1
82 | ```
83 |
84 |
85 |
86 | ### 2.2 安装 Llamaindex 与 Pytorch
87 |
88 | 安装 `Llamaindex` 和相关的包:
89 |
90 | ```bash
91 | conda activate llamaindex
92 | pip install llama-index==0.10.38 llama-index-llms-huggingface==0.2.0 "transformers[torch]==4.41.1" "huggingface_hub[inference]==0.23.1" huggingface_hub==0.23.1 sentence-transformers==2.7.0 sentencepiece==0.2.0
93 | ```
94 |
95 | 安装 `LlamaIndex` 词嵌入向量依赖:
96 |
97 | ```bash
98 | conda activate llamaindex
99 | pip install llama-index-embeddings-huggingface==0.2.0 llama-index-embeddings-instructor==0.1.3
100 | ```
101 |
102 | ```bash
103 | 在这一步请确定llama-index-embeddings-huggingface安装成功
104 | 如果存在not found错误,请重新安装
105 | # pip install llama-index-embeddings-huggingface==0.2.0
106 | 确保 huggingface_hub==0.23.1
107 | ```
108 |
109 | 最后再安装 Pytorch:
110 | ```bash
111 | conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia
112 | ```
113 |
114 | 安装完成后,验证 Pytorch 是否正确安装并使用了指定的 CUDA 版本:
115 | ```
116 | import torch
117 | print(torch.__version__) # 应输出类似 '2.0.1'
118 | print(torch.version.cuda) # 应输出 '11.7'
119 | print(torch.cuda.is_available())# 应输出 True
120 | ```
121 |
122 |
123 | 关于 LlamaIndex 与 Pytorch 安装顺序的说明
124 |
125 | ---
126 |
127 | 关于本次实验的运行环境,我们建议的是如上 先安装 Llamaindex ,再安装 Pytorch。
128 |
129 | “先安装 Pytorch 再安装 Llamaindex”存在的问题是:匹配CUDA 11.7的torch安装在前,但是其后安装 LLamaIndex 相关的指令会稳定触发torch的升级到最新版本,而新版本的PyTorch (2.5.1) 默认使用CUDA 12.4,导致 Pytorch 版本与 CUDA版本不匹配。
130 |
131 | 这样,当进行到模型推理的步骤时,就会报错:
132 | ```
133 | RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)
134 | ```
135 |
136 | 这时候就需要再次**重新**安装正确的torch:
137 | ```
138 | conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia
139 | ```
140 |
141 | 导致操作步骤的繁杂与冗余。
142 |
143 | ---
144 |
145 |
146 | ### 2.3 下载 Sentence Transformer 模型
147 |
148 | 源词向量模型 [Sentence Transformer](https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2):(我们也可以选用别的开源词向量模型来进行 Embedding,目前选用这个模型是相对轻量、支持中文且效果较好的,同学们可以自由尝试别的开源词向量模型)
149 | 运行以下指令,新建一个 python 文件
150 |
151 | ```bash
152 | cd ~
153 | mkdir llamaindex_demo
154 | mkdir model
155 | cd ~/llamaindex_demo
156 | touch download_hf.py
157 | ```
158 |
159 | 打开`download_hf.py` 贴入以下代码
160 |
161 | ```bash
162 | import os
163 |
164 | # 设置环境变量
165 | os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
166 |
167 | # 下载模型
168 | os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/model/sentence-transformer')
169 | ```
170 |
171 | 然后,在 /root/llamaindex_demo 目录下执行该脚本即可自动开始下载:
172 |
173 | ```bash
174 | cd /root/llamaindex_demo
175 | conda activate llamaindex
176 | python download_hf.py
177 | ```
178 |
179 | 更多关于镜像使用可以移步至 [HF Mirror](https://hf-mirror.com/) 查看。
180 |
181 | ### 2.4 下载 NLTK 相关资源
182 |
183 | 我们在使用开源词向量模型构建开源词向量的时候,需要用到第三方库 `nltk` 的一些资源。正常情况下,其会自动从互联网上下载,但可能由于网络原因会导致下载中断,此处我们可以从国内仓库镜像地址下载相关资源,保存到服务器上。
184 | 我们用以下命令下载 nltk 资源并解压到服务器上:
185 |
186 | ```bash
187 | cd /root
188 | git clone https://gitee.com/yzy0612/nltk_data.git --branch gh-pages
189 | cd nltk_data
190 | mv packages/* ./
191 | cd tokenizers
192 | unzip punkt.zip
193 | cd ../taggers
194 | unzip averaged_perceptron_tagger.zip
195 | ```
196 |
197 | 之后使用时服务器即会自动使用已有资源,无需再次下载
198 |
199 | ## 3. LlamaIndex HuggingFaceLLM
200 |
201 | 运行以下指令,把 `InternLM2 1.8B` 软连接出来
202 |
203 | ```bash
204 | cd ~/model
205 | ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b/ ./
206 | ```
207 |
208 | 运行以下指令,新建一个 python 文件
209 |
210 | ```bash
211 | cd ~/llamaindex_demo
212 | touch llamaindex_internlm.py
213 | ```
214 |
215 | 打开 llamaindex_internlm.py 贴入以下代码
216 |
217 | ```python
218 | from llama_index.llms.huggingface import HuggingFaceLLM
219 | from llama_index.core.llms import ChatMessage
220 | llm = HuggingFaceLLM(
221 | model_name="/root/model/internlm2-chat-1_8b",
222 | tokenizer_name="/root/model/internlm2-chat-1_8b",
223 | model_kwargs={"trust_remote_code":True},
224 | tokenizer_kwargs={"trust_remote_code":True}
225 | )
226 |
227 | rsp = llm.chat(messages=[ChatMessage(content="xtuner是什么?")])
228 | print(rsp)
229 | ```
230 |
231 | 之后运行
232 |
233 | ```bash
234 | conda activate llamaindex
235 | cd ~/llamaindex_demo/
236 | python llamaindex_internlm.py
237 | ```
238 |
239 | 结果为:
240 | 
241 | 回答的效果并不好,并不是我们想要的 xtuner。
242 |
243 | ## 4. LlamaIndex RAG
244 |
245 | 运行以下命令,获取知识库
246 |
247 | ```bash
248 | cd ~/llamaindex_demo
249 | mkdir data
250 | cd data
251 | git clone https://github.com/InternLM/xtuner.git
252 | mv xtuner/README_zh-CN.md ./
253 | ```
254 |
255 | 运行以下指令,新建一个 python 文件
256 |
257 | ```bash
258 | cd ~/llamaindex_demo
259 | touch llamaindex_RAG.py
260 | ```
261 |
262 | 打开`llamaindex_RAG.py`贴入以下代码
263 |
264 | ```python
265 |
266 | from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
267 |
268 | from llama_index.embeddings.huggingface import HuggingFaceEmbedding
269 | from llama_index.llms.huggingface import HuggingFaceLLM
270 |
271 | #初始化一个HuggingFaceEmbedding对象,用于将文本转换为向量表示
272 | embed_model = HuggingFaceEmbedding(
273 | #指定了一个预训练的sentence-transformer模型的路径
274 | model_name="/root/model/sentence-transformer"
275 | )
276 | #将创建的嵌入模型赋值给全局设置的embed_model属性,
277 | #这样在后续的索引构建过程中就会使用这个模型。
278 | Settings.embed_model = embed_model
279 |
280 | llm = HuggingFaceLLM(
281 | model_name="/root/model/internlm2-chat-1_8b",
282 | tokenizer_name="/root/model/internlm2-chat-1_8b",
283 | model_kwargs={"trust_remote_code":True},
284 | tokenizer_kwargs={"trust_remote_code":True}
285 | )
286 | #设置全局的llm属性,这样在索引查询时会使用这个模型。
287 | Settings.llm = llm
288 |
289 | #从指定目录读取所有文档,并加载数据到内存中
290 | documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
291 | #创建一个VectorStoreIndex,并使用之前加载的文档来构建索引。
292 | # 此索引将文档转换为向量,并存储这些向量以便于快速检索。
293 | index = VectorStoreIndex.from_documents(documents)
294 | # 创建一个查询引擎,这个引擎可以接收查询并返回相关文档的响应。
295 | query_engine = index.as_query_engine()
296 | response = query_engine.query("xtuner是什么?")
297 |
298 | print(response)
299 | ```
300 |
301 | 之后运行
302 |
303 | ```bash
304 | conda activate llamaindex
305 | cd ~/llamaindex_demo/
306 | python llamaindex_RAG.py
307 | ```
308 |
309 | 结果为:
310 | 
311 |
312 | 借助 RAG 技术后,就能获得我们想要的答案了。
313 |
314 | ## 5. LlamaIndex web
315 |
316 | 运行之前首先安装依赖
317 |
318 | ```shell
319 | pip install streamlit==1.36.0
320 | ```
321 |
322 | 运行以下指令,新建一个 python 文件
323 |
324 | ```bash
325 | cd ~/llamaindex_demo
326 | touch app.py
327 | ```
328 |
329 | 打开`app.py`贴入以下代码
330 |
331 | ```python
332 | import streamlit as st
333 | from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
334 | from llama_index.embeddings.huggingface import HuggingFaceEmbedding
335 | from llama_index.llms.huggingface import HuggingFaceLLM
336 |
337 | st.set_page_config(page_title="llama_index_demo", page_icon="🦜🔗")
338 | st.title("llama_index_demo")
339 |
340 | # 初始化模型
341 | @st.cache_resource
342 | def init_models():
343 | embed_model = HuggingFaceEmbedding(
344 | model_name="/root/model/sentence-transformer"
345 | )
346 | Settings.embed_model = embed_model
347 |
348 | llm = HuggingFaceLLM(
349 | model_name="/root/model/internlm2-chat-1_8b",
350 | tokenizer_name="/root/model/internlm2-chat-1_8b",
351 | model_kwargs={"trust_remote_code": True},
352 | tokenizer_kwargs={"trust_remote_code": True}
353 | )
354 | Settings.llm = llm
355 |
356 | documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
357 | index = VectorStoreIndex.from_documents(documents)
358 | query_engine = index.as_query_engine()
359 |
360 | return query_engine
361 |
362 | # 检查是否需要初始化模型
363 | if 'query_engine' not in st.session_state:
364 | st.session_state['query_engine'] = init_models()
365 |
366 | def greet2(question):
367 | response = st.session_state['query_engine'].query(question)
368 | return response
369 |
370 |
371 | # Store LLM generated responses
372 | if "messages" not in st.session_state.keys():
373 | st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
374 |
375 | # Display or clear chat messages
376 | for message in st.session_state.messages:
377 | with st.chat_message(message["role"]):
378 | st.write(message["content"])
379 |
380 | def clear_chat_history():
381 | st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
382 |
383 | st.sidebar.button('Clear Chat History', on_click=clear_chat_history)
384 |
385 | # Function for generating LLaMA2 response
386 | def generate_llama_index_response(prompt_input):
387 | return greet2(prompt_input)
388 |
389 | # User-provided prompt
390 | if prompt := st.chat_input():
391 | st.session_state.messages.append({"role": "user", "content": prompt})
392 | with st.chat_message("user"):
393 | st.write(prompt)
394 |
395 | # Gegenerate_llama_index_response last message is not from assistant
396 | if st.session_state.messages[-1]["role"] != "assistant":
397 | with st.chat_message("assistant"):
398 | with st.spinner("Thinking..."):
399 | response = generate_llama_index_response(prompt)
400 | placeholder = st.empty()
401 | placeholder.markdown(response)
402 | message = {"role": "assistant", "content": response}
403 | st.session_state.messages.append(message)
404 | ```
405 |
406 | 之后运行
407 |
408 | ```bash
409 | streamlit run app.py
410 | ```
411 |
412 | 然后在命令行点击,红框里的 url。
413 |
414 | 
415 |
416 | 即可进入以下网页,然后就可以开始尝试问问题了。
417 |
418 | 
419 |
420 | 询问结果为:
421 |
422 | 
423 |
424 | ## 6. 小结
425 |
426 | 恭喜你,成功通关本关卡!继续加油!你成功使用 LlamaIndex 运行了 InternLM-2 1.8B 模型,并实现了知识库的构建与检索。这为管理和利用大规模知识库提供了强大的工具和方法。接下来,可以进一步优化和扩展功能,以满足更复杂的需求。
427 |
428 | ## 7. 作业
429 |
430 | 作业请访问[作业](./task.md)。
431 |
--------------------------------------------------------------------------------
/docs/L1/LlamaIndex/task.md:
--------------------------------------------------------------------------------
1 | # Llamaindex RAG 实践
2 |
3 | ## 基础任务 (完成此任务即完成闯关)
4 |
5 | - **任务要求1(必做,参考readme_api.md)**:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前 浦语 API 不会回答,借助 LlamaIndex 后 浦语 API 具备回答 A 的能力,截图保存。**注意:写博客提交作业时切记不要泄漏自己 api_key!**
6 |
7 | - **任务要求2(可选,参考readme.md)**:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前 InternLM2-Chat-1.8B 模型不会回答,借助 LlamaIndex 后 InternLM2-Chat-1.8B 模型具备回答 A 的能力,截图保存。
8 | - **任务要求3(优秀学员必做)** :将 Streamlit+LlamaIndex+浦语API的 Space 部署到 Hugging Face。
9 |
10 | ## 闯关材料提交 (完成任务并且提交材料时为闯关成功)
11 |
12 | - 请将作业发布到知乎、CSDN 等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
13 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
14 |
--------------------------------------------------------------------------------
/docs/L1/Prompt/README.md:
--------------------------------------------------------------------------------
1 | # 提示工程(Prompt Engineering)
2 |
3 |
4 | 
5 |
6 |
7 | ## 1.1 什么是Prompt(提示词)
8 |
9 | Prompt是一种用于指导以大语言模型为代表的**生成式人工智能**生成内容(文本、图像、视频等)的输入方式。它通常是一个简短的文本或问题,用于描述任务和要求。
10 |
11 | Prompt可以包含一些特定的关键词或短语,用于引导模型生成符合特定主题或风格的内容。例如,如果我们要生成一篇关于“人工智能”的文章,我们可以使用“人工智能”作为Prompt,让模型生成一篇关于人工智能的介绍、应用、发展等方面的文章。
12 |
13 | Prompt还可以包含一些特定的指令或要求,用于控制生成文本的语气、风格、长度等方面。例如,我们可以使用“请用幽默的语气描述人工智能的发展历程”作为Prompt,让模型生成一篇幽默风趣的文章。
14 |
15 | 总之,Prompt是一种灵活、多样化的输入方式,可以用于指导大语言模型生成各种类型的内容。
16 |
17 | 
18 |
19 | ## 1.2 什么是提示工程
20 |
21 | 提示工程是一种通过设计和调整输入(Prompts)来改善模型性能或控制其输出结果的技术。
22 |
23 | 在模型回复的过程中,首先获取用户输入的文本,然后处理文本特征并根据输入文本特征预测之后的文本,原理为**next token prediction**,类似我们日常使用的输入法。
24 |
25 |
26 | 
27 |
28 |
29 | 提示工程是模型性能优化的基石,有以下六大基本原则:
30 |
31 | - 指令要清晰
32 | - 提供参考内容
33 | - 复杂的任务拆分成子任务
34 | - 给 LLM“思考”时间(给出过程)
35 | - 使用外部工具
36 | - 系统性测试变化
37 |
38 |
39 | 在提示工程中,第一点给出清晰的指令是至关重要的。一个有效的指令通常包含以下要素:背景、任务、要求、限制条件、示例、输出格式和目标。通过提供这些详细信息,我们可以引导模型生成更符合我们期望的文本。
40 |
41 | 让我们以"为AI大模型训练营生成介绍文案"为例,来展示如何逐步优化指令,以获得更理想的AI生成内容:
42 |
43 | 第一版提示词(基础版):
44 | ```
45 | 写一段话介绍AI大模型训练营
46 | ```
47 |
48 | 
49 |
50 |
51 | 第二版提示词(增加表情元素):
52 | ```
53 | 写一段话介绍AI大模型训练营,添加emoji表情
54 | ```
55 |
56 | 
57 |
58 |
59 | 第三版提示词(进一步优化结构):
60 | ```
61 | 写一段话介绍AI大模型训练营,添加emoji表情,结构化排版
62 | ```
63 |
64 | 
65 |
66 |
67 | 通过这个例子,我们可以清楚地看到,随着指令的逐步完善,AI生成的内容质量也随之提升。这种渐进式的提示词优化方法可以帮助我们更好地掌控AI输出,获得更符合需求的结果。
68 |
69 | 其他技巧我们这里不做过多介绍,如果大家感兴趣可以参考下面的资料:
70 |
71 | * [OpenAI 官方提示工程指南](https://platform.openai.com/docs/guides/prompt-engineering)
72 | * [Claude 官方提示工程指南](https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview)
73 | * [LangGPT 知识库](https://langgptai.feishu.cn/wiki/RXdbwRyASiShtDky381ciwFEnpe)
74 | * [万字解读ChatGPT提示词最佳案例](https://langgptai.feishu.cn/wiki/IpdUwZRzgiYYH7kuOsDc3fWrnkg)
75 |
76 |
77 | ## 1.3 提示设计框架
78 |
79 | - CRISPE,参考:[https://github.com/mattnigh/ChatGPT3-Free-Prompt-List](https://github.com/mattnigh/ChatGPT3-Free-Prompt-List)
80 |
81 | - **C**apacity and **R**ole (能力与角色):希望 ChatGPT 扮演怎样的角色。
82 | - **I**nsight (洞察力):背景信息和上下文(坦率说来我觉得用 Context 更好)
83 | - **S**tatement (指令):希望 ChatGPT 做什么。
84 | - **P**ersonality (个性):希望 ChatGPT 以什么风格或方式回答你。
85 | - **E**xperiment (尝试):要求 ChatGPT 提供多个答案。
86 |
87 | 写出的提示如下:
88 |
89 | ```
90 | Act as an expert on software development on the topic of machine learning frameworks, and an expert blog writer. The audience for this blog is technical professionals who are interested in learning about the latest advancements in machine learning. Provide a comprehensive overview of the most popular machine learning frameworks, including their strengths and weaknesses. Include real-life examples and case studies to illustrate how these frameworks have been successfully used in various industries. When responding, use a mix of the writing styles of Andrej Karpathy, Francois Chollet, Jeremy Howard, and Yann LeCun.
91 | ```
92 |
93 | - CO-STAR,参考:[https://aiadvisoryboards.wordpress.com/2024/01/30/co-star-framework/](https://aiadvisoryboards.wordpress.com/2024/01/30/co-star-framework/)
94 |
95 | 
96 |
97 | - **C**ontext (背景): 提供任务背景信息
98 | - **O**bjective (目标): 定义需要LLM执行的任务
99 | - **S**tyle (风格): 指定希望LLM具备的写作风格
100 | - **T**one (语气): 设定LLM回复的情感基调
101 | - **A**udience (观众): 表明回复的对象
102 | - **R**esponse (回复): 提供回复格式
103 |
104 | 例如我们设计一个解决方案专家,用于把目标拆解为可执行的计划,完成的提示词如下:
105 |
106 | ```
107 | # CONTEXT #
108 | 我是一名个人生产力开发者。在个人发展和生产力领域,人们越来越需要这样的系统:不仅能帮助个人设定目标,还能将这些目标转化为可行的步骤。许多人在将抱负转化为具体行动时遇到困难,凸显出需要一个有效的目标到系统的转换过程。
109 |
110 | #########
111 |
112 | # OBJECTIVE #
113 | 您的任务是指导我创建一个全面的系统转换器。这涉及将过程分解为不同的步骤,包括识别目标、运用5个为什么技巧、学习核心行动、设定意图以及进行定期回顾。目的是提供一个逐步指南,以无缝地将目标转化为可行的计划。
114 |
115 | #########
116 |
117 | # STYLE #
118 | 以富有信息性和教育性的风格写作,类似于个人发展指南。确保每个步骤的呈现都清晰连贯,迎合那些渴望提高生产力和实现目标技能的受众。
119 |
120 | #########
121 |
122 | # Tone #
123 | 始终保持积极和鼓舞人心的语气,培养一种赋权和鼓励的感觉。应该感觉像是一位友好的向导在提供宝贵的见解。
124 |
125 | # AUDIENCE #
126 | 目标受众是对个人发展和提高生产力感兴趣的个人。假设读者寻求实用建议和可行步骤,以将他们的目标转化为切实的成果。
127 |
128 | #########
129 |
130 | # RESPONSE FORMAT #
131 | 提供一个结构化的目标到系统转换过程步骤列表。每个步骤都应该清晰定义,整体格式应易于遵循以便快速实施。
132 |
133 | #############
134 |
135 | # START ANALYSIS #
136 | 如果您理解了,请询问我的目标。
137 | ```
138 |
139 | # 2. LangGPT结构化提示词
140 |
141 | LangGPT 是 **Language For GPT-like LLMs** 的简称,中文名为结构化提示词。LangGPT 是一个帮助你编写高质量提示词的工具,理论基础是我们提出的一套模块化、标准化的提示词编写方法论——结构化提示词。我们希望揭开提示工程的神秘面纱,为大众提供一套可操作、可复现的提示词方法论、工具和交流社群。我们的愿景是让人人都能写出高质量提示词。[LangGPT社区文档](https://langgptai.feishu.cn/wiki/RXdbwRyASiShtDky381ciwFEnpe):https://langgpt.ai
142 |
143 | ## 2.1 LangGPT结构
144 |
145 | LangGPT框架参考了面向对象程序设计的思想,设计为基于角色的双层结构,一个完整的提示词包含**模块-内部元素**两级,模块表示要求或提示LLM的方面,例如:背景信息、建议、约束等。内部元素为模块的组成部分,是归属某一方面的具体要求或辅助信息,分为赋值型和方法型。
146 |
147 | 
148 |
149 | ## 2.2 编写技巧
150 |
151 | - **构建全局思维链**
152 |
153 | 对大模型的 Prompt 应用CoT 思维链方法的有效性是被研究和实践广泛证明了的。首先可以根据场景选择基本的模块。
154 |
155 | 
156 |
157 | **一个好的结构化 Prompt 模板,某种意义上是构建了一个好的全局思维链。** 如 LangGPT 中展示的模板设计时就考虑了如下思维链:
158 |
159 | > 💡 Role (角色) -> Profile(角色简介)—> Profile 下的 skill (角色技能) -> Rules (角色要遵守的规则) -> Workflow (满足上述条件的角色的工作流程) -> Initialization (进行正式开始工作的初始化准备) -> 开始实际使用
160 |
161 | 一个好的 Prompt ,内容结构上最好也是逻辑清晰连贯的。**结构化 prompt 方法将久经考验的逻辑思维链路融入了结构中,大大降低了思维链路的构建难度。**
162 |
163 | 构建 Prompt 时,不妨参考优质模板的全局思维链路,熟练掌握后,完全可以对其进行增删改留调整得到一个适合自己使用的模板。例如当你需要控制输出格式,尤其是需要格式化输出时,完全可以增加 `Output` 或者 `OutputFormat` 这样的模块。
164 |
165 | - **保持上下文语义一致性**
166 |
167 | 包含两个方面,一个是**格式语义一致性**,一个是**内容语义一致性**。
168 |
169 | **格式语义一致性是指标识符的标识功能前后一致。** 最好不要混用,比如 `#` 既用于标识标题,又用于标识变量这种行为就造成了前后不一致,这会对模型识别 Prompt 的层级结构造成干扰。
170 |
171 | **内容语义一致性是指思维链路上的属性词语义合适。** 例如 LangGPT 中的 `Profile` 属性词,使之功能更加明确:即角色的简历。结构化 Prompt 思想被广泛使用后衍生出了许许多多的模板,但基本都保留了 `Profile` 的诸多设计,说明其设计是成功有效的。
172 |
173 | **内容语义一致性还包括属性词和相应模块内容的语义一致。** 例如 `Rules` 部分是角色需要遵守规则,则不宜将角色技能、描述大量堆砌在此。
174 |
175 | - **有机结合其他 Prompt 技巧**
176 |
177 | LangGPT结构在设计时没有拘泥于具体的方面,相比其他的提示设计框架,更加灵活,具有更强的可扩展性和兼容性,可以很好地结合其他提示设计技巧。
178 |
179 | 构建高质量 Prompt 时,将这些方法结合使用,结构化方式能够更便于各个技巧间的协同组织,例如将 CoT 方法融合到结构化 Prompt 中编写提示词。
180 | 汇总现有的一些方法:
181 |
182 | 1. 细节法:给出更清晰的指令,包含更多具体的细节
183 | 2. 分解法:将复杂的任务分解为更简单的子任务 (Let's think step by step, CoT,LangChain等思想)
184 | 3. 记忆法:构建指令使模型时刻记住任务,确保不偏离任务解决路径(system 级 prompt)
185 | 4. 解释法:让模型在回答之前进行解释,说明理由 (CoT 等方法)
186 | 5. 投票法:让模型给出多个结果,然后使用模型选择最佳结果 (ToT 等方法)
187 | 6. 示例法:提供一个或多个具体例子,提供输入输出示例 (one-shot, few-shot 等方法)
188 |
189 | 上面这些方法最好结合使用,以实现在复杂任务中实现使用不可靠工具(LLMs)构建可靠系统的目标。
190 |
191 | ## 2.3 常用的提示词模块
192 | 结构化提示词更多体现的是一种思想,本章所给出的提示词模板也只是当前的最佳实践,实际使用过程中大家可以根据需要自行增删各个模块,重构相关模块,甚至提出一套全新的模板。
193 |
194 | 编写提示词时,需要根据不同需求添加不同模块要点。如果采用固定的模式写法,在面对差异巨大的需求场景时,经常会因缺少某些描述而导致效果变差。下面整理了按字母从A-Z排列的共30个角度的模块,使用时,可从其中挑选合适的模块组装。
195 |
196 | - Attention:需重点强调的要点
197 | - Background:提示词的需求背景
198 | - Constraints:限制条件
199 | - Command:用于定义大模型指令
200 | - Definition:名词定义
201 | - Example:提示词中的示例few-shots
202 | - Fail:处理失败时对应的兜底逻辑
203 | - Goal:提示词要实现的目标
204 | - Hack:防止被攻击的防护词
205 | - In-depth:一步步思考,持续深入
206 | - Job:需求任务描述
207 | - Knowledge:知识库文件
208 | - Lawful:合法合规,安全行驶的限制
209 | - Memory:记忆关键信息,缓解模型遗忘问题
210 | - Merge:是否使用多角色,最终合并投票输出结果
211 | - Neglect:明确忽略哪些内容
212 | - Odd:偶尔 (俏皮,愤怒,严肃) 一下
213 | - OutputFormat:模型输出格式
214 | - Pardon:当用户回复信息不详细时,持续追问
215 | - Quote:引用知识库信息时,给出原文引用链接
216 | - Role:大模型的角色设定
217 | - RAG:外挂知识库
218 | - Skills:擅长的技能项
219 | - Tone:回复使用的语气风格
220 | - Unsure:引入评判者视角,当判定低于阈值时,回复安全词
221 | - Vaule:Prompt模仿人格的价值观
222 | - Workflow:工作流程
223 | - X-factor:用户使用本提示词最为重要的内核要素
224 | - Yeow:提示词开场白设计
225 | - Zig:无厘头式提示词,如[答案之书]
226 |
227 |
228 | # 3. 浦语提示词工程实践(LangGPT版)
229 |
230 | 编写完LangGPT提示词后,可以将其作为系统提示,也可直接作为交互式对话的输入。**推荐作为系统提示**。
231 |
232 | 
233 |
234 | 填入系统提示后保存设置,之后可以与自定义的助手角色进行对话。
235 |
236 | ## 3.1 自动化生成LangGPT提示词
237 |
238 | 利用下面的提示词引导InternLM扮演提示词生成助手,自动化地生成符合最佳实践的结构化提示词:
239 | ```
240 | 你是提示词专家,根据用户的输入设计用于生成**高质量(清晰准确)**的大语言模型提示词。
241 | - 技能:
242 | - 📊 分析、写作、编码
243 | - 🚀 自动执行任务
244 | - ✍ 遵循提示工程的行业最佳实践并生成提示词
245 | # 输出要求:
246 | - 结构化输出内容。
247 | - 为代码或文章提供**详细、准确和深入**的内容。
248 | # 📝 提示词模板(使用代码块展示提示内容):
249 | ```
250 | 你是xxx(描述角色和角色任务)
251 | - 技能:
252 | - 📊 分析、写作、编码
253 | - 🚀 自动执行任务
254 | # 💬 输出要求:
255 | - 结构化输出内容。
256 | - 为代码或文章提供**详细、准确和深入**的内容。
257 | -(其他基本输出要求)
258 | # 🔧 工作流程:
259 | - 仔细深入地思考和分析用户的内容和意图。
260 | - 逐步工作并提供专业和深入的回答。
261 | -(其他基本对话工作流程)
262 | # 🌱 初始化:
263 | 欢迎用户,友好的介绍自己并引导用户使用。
264 | ```
265 | **你的任务是帮助用户设计高质量提示词。**
266 | 开始请打招呼:“您好!我是您的提示词专家助手,请随时告诉我您需要设计什么用途的提示词吧。
267 | ```
268 |
269 | 效果演示:
270 |
271 | 
272 |
273 |
274 |
275 | ## 3.2 小红书文案专家
276 |
277 | 利用下面的提示词引导InternLM扮演小红书文案专家,撰写符合小红书平台特色的小红书:
278 |
279 | ```markdown
280 | 你是小红书文案专家,请按照我提供的主题,帮我创作小红书标题和文案。
281 |
282 | # 技能
283 |
284 | ## 创作有吸引力的标题
285 | - 使用标点:通过标点符号,尤其是叹号,增强语气,创造紧迫或惊喜的感觉!
286 | - 挑战与悬念:提出引人入胜的问题或情境,激发好奇心。
287 | - 结合正负刺激:平衡使用正面和负面的刺激,吸引注意力。
288 | - 紧跟热点:融入当前流行的热梗、话题和实用信息。
289 | - 明确成果:具体描述产品或方法带来的实际效果。
290 | - 表情符号:适当使用emoji,增加活力和趣味性。
291 | - 口语化表达:使用贴近日常交流的语言,增强亲和力。
292 | - 字数控制:保持标题在20字以内,简洁明了。
293 |
294 | ## 标题创作公式
295 | 标题需要顺应人类天性,追求便捷与快乐,避免痛苦。
296 | - 正面吸引:展示产品或方法的惊人效果,强调快速获得的益处。比如:产品或方法+只需1秒(短期)+便可开挂(逆天效果)。
297 | - 负面警示:指出不采取行动可能带来的遗憾和损失,增加紧迫感。比如:你不xxx+绝对会后悔(天大损失)+(紧迫感)
298 |
299 | 标题从下面选择1-2个关键词:
300 | 我宣布、我不允许、请大数据把我推荐给、真的好用到哭、真的可以改变阶级、真的不输、永远可以相信、吹爆、搞钱必看、狠狠搞钱、一招拯救、正确姿势、正确打开方式、摸鱼暂停、停止摆烂、救命!、啊啊啊啊啊啊啊!、以前的...vs现在的...、再教一遍、再也不怕、教科书般、好用哭了、小白必看、宝藏、绝绝子、神器、都给我冲、划重点、打开了新世界的大门、YYDS、秘方、压箱底、建议收藏、上天在提醒你、挑战全网、手把手、揭秘、普通女生、沉浸式、有手就行、打工人、吐血整理、家人们、隐藏、高级感、治愈、破防了、万万没想到、爆款、被夸爆
301 |
302 | ## 创作有吸引力的正文:
303 |
304 | ### 正文创作公式
305 | 选择以下一种方式作为文章的开篇引入:
306 | - 引用名言、提出问题、使用夸张数据、举例说明、前后对比、情感共鸣。
307 |
308 | ### 正文要求
309 | - 风格要求:真诚友好、鼓励建议、幽默轻松;口语化的表达风格,有共情力
310 | - 多用叹号、多分段、多用短句
311 | - 重点在前:遵循倒金字塔原则,把最重要的事情放在开头说明
312 | - 逻辑清晰:遵循总分总原则,第一段和结尾段总结,中间段分点说明
313 |
314 | # 输出要求:
315 | - 标题数量:每次准备10个标题。
316 | - 正文创作:撰写与标题相匹配的正文内容,具有强烈的浓人风格
317 |
318 | # 🔧 工作流程:
319 | - 请用户提供关键词或主题,确定文案的方向和风格。
320 | - 根据用户主题,自动生成符合小红书平台特点的文案,包括标题、正文和 Tags。
321 |
322 | # 🌱 初始化:
323 | 欢迎用户,友好的介绍自己。请用户提供关键词或主题,以及期望的文案风格和目标用户群体,依据用户提供的主题创作文案。
324 | ```
325 |
326 | 效果演示:
327 |
328 | 
329 |
330 |
331 | ## 3.3 应用开发实战
332 | 参考文档:[使用浦语 InternLM 大模型一键写书](./practice.md)
333 |
334 |
335 | # 本章小结
336 |
337 | 本章深入探讨了提示工程(Prompt Engineering)的理论与实践,从基础概念到高级应用,为读者提供了全面的学习路径。
338 |
339 | 我们首先介绍了提示词(Prompt)的定义及其在生成式人工智能中的重要作用。随后,我们探讨了提示工程的基本原则和技巧,包括CRISPE和CO-STAR等常见的提示词设计框架。
340 |
341 | 接着,我们重点介绍了LangGPT结构化提示词方法。这种方法借鉴了面向对象程序设计的思想,提供了一种模块化、标准化的提示词编写方法论。我们详细讲解了LangGPT的基本结构、编写技巧以及常用模块,为读者提供了实用的工具来提高提示词的质量和效果。
342 |
343 | 在实践部分,我们展示了如何使用浦语大模型进行提示工程实践。通过具体的案例,如自动化生成提示词和小红书文案助手,我们展示了LangGPT框架在实际应用中的强大功能。
344 |
345 | 最后,我们通过一个"一键写书"系统的开发实战,将理论知识应用到实际项目中。我们详细讲解了项目的架构、核心代码实现,以及潜在的优化方向,为读者提供了一个综合性的学习案例。
346 |
347 | 通过本章的学习,读者应该能够理解提示工程的核心概念,掌握LangGPT结构化提示词的编写方法,并能够将这些知识应用到实际的AI应用开发中。同时,我们也鼓励读者在此基础上进行进一步的探索和创新,以充分发挥大语言模型的潜力。
--------------------------------------------------------------------------------
/docs/L1/Prompt/practice.md:
--------------------------------------------------------------------------------
1 |
2 | ## 应用开发实战:使用浦语 InternLM 大模型一键写书
3 |
4 | ### 1 在线体验(需正确上网):
5 | https://book.apps.langgpt.ai/
6 |
7 | ### 2 本地运行:
8 |
9 | #### 2.1 获取项目代码
10 | 项目地址: https://github.com/langgptai/BookAI
11 | 命令:
12 | ```
13 | git clone https://github.com/langgptai/BookAI.git
14 | cd BookAI
15 | ```
16 |
17 | 查看项目结构:
18 | ```
19 | ├── book_writer.py
20 | ├── prompts
21 | │ ├── chapter_writer.txt
22 | │ ├── outline_writer.txt
23 | │ └── title_writer.txt
24 | ├── README.md
25 | ├── requirements.txt
26 | ```
27 | #### 2.2 配置项目 Python 环境
28 | ```
29 | pip install -r requirements.txt
30 | ```
31 |
32 | #### 2.3 配置大模型 API
33 |
34 | (1)申请浦语的 API , 获取 API Token:
35 | https://internlm.intern-ai.org.cn/api/document
36 |
37 |
38 | (2) 修改下面命令中的 API_KEY 等配置,在命令行执行命令,即可完成书籍创作
39 |
40 | ```
41 | export API_KEY=xxx
42 | export BASE_URL=https://internlm-chat.intern-ai.org.cn/puyu/api/v1/
43 | export MODEL_NAME=internlm2.5-latest
44 |
45 | python3 book_writer.py
46 | ```
47 | (3)创作好的书籍在 books 文件夹下,写好的书籍示例(仅供参考): [爱的编码:解密人类情感基因](./book.md).
48 |
49 | (4)注意:
50 |
51 | > 如果遇到“请求过于频繁,请稍后再试”报错,是 API 存在调用频率限制,可以使用[硅基流动](https://cloud.siliconflow.cn/i/TxUlXG3u)注册免费的 API 服务。配置 API_KEY,修改下面的命令并执行:
52 |
53 | 注意:写博客时切记删除自己的 api_key!
54 |
55 |
56 | ```
57 | export API_KEY=sk-xxx
58 | export BASE_URL=https://api.siliconflow.cn/v1
59 | export MODEL_NAME=internlm/internlm2_5-7b-chat
60 |
61 | python3 book_writer.py
62 | ```
63 |
64 | #### 2.4 项目拆解
65 |
66 | 大模型无法完成这么复杂的任务,因此我们需要拆解任务 ——> 这种方法也称为分治法。
67 |
68 | 分治法拆解任务:
69 | - 第一步:创作书籍总体信息:书名,主要内容介绍
70 | - 第二步:创作书籍分章节大纲:每章章节名+简介
71 | - 第三步:依据章节大纲创作章节内容
72 |
73 | 接下来针对每一步骤撰写提示词:
74 |
75 | (1)书籍起名提示词
76 | ```
77 | # Role: 书籍写作专家
78 |
79 | ## Profile
80 | - author: LangGPT
81 | - version: 1.0
82 | - language: 中文
83 | - description: 帮助用户为书籍创建有吸引力的标题和简介,确保书名与书籍内容相符,简介清晰传达书籍核心主题。
84 |
85 | ## Skills
86 | 1. 创意标题设计:能够根据书籍主题与风格,设计简洁、吸引读者的书名。
87 | 2. 精准简介编写:擅长提炼书籍的核心内容,用简短的文字清晰传达书籍的主题和卖点。
88 | 3. 内容风格匹配:根据书籍类型(小说、纪实、科幻等),调整标题和简介的语言风格。
89 | 4. 阅读者定位:根据书籍目标读者群体,设计有针对性的书籍标题与简介。
90 |
91 | ## Rules
92 | 1. 根据书籍内容概述、类型和目标读者,生成适合的标题和简介。
93 | 2. 标题需简洁、富有吸引力,能够激发读者的兴趣。
94 | 3. 简介需简短有力,准确传达书籍核心内容和主题。
95 | 4. 避免过于复杂或不相关的描述,突出书籍卖点和读者关心的部分。
96 |
97 | ## Goals
98 | 书籍信息:{theme}
99 | 撰写书籍标题和简介(json格式输出):
100 | {
101 | "title":"《xxx》",
102 | "intro":"xxx",
103 | }
104 |
105 | ## Init
106 | 设计合适的标题和简介,只输出json内容,此外不要给出任何无关内容和字符。
107 | ```
108 |
109 |
110 | (2) 书籍大纲提示词
111 | ```
112 | # Role: 书籍写作专家
113 |
114 | ## Profile
115 | - author: LangGPT
116 | - version: 1.0
117 | - language: 中文/英文
118 | - description: 帮助用户根据书籍的标题和简介,设计出完整的书籍大纲,确保结构清晰,逻辑合理,并符合书籍的主题和风格。
119 |
120 | ## Skills
121 | 1. 书籍结构设计:根据书籍的主题和内容,设计清晰、有逻辑的章节和段落结构。
122 | 2. 情节和主题发展:擅长为小说、纪实文学等书籍设计情节发展框架,确保每一章节之间的连贯性和发展方向。
123 | 3. 内容层次划分:能够根据书籍的核心主题,将内容分为多个合理的层次和部分,确保读者能系统地理解内容。
124 | 4. 读者体验优化:根据目标读者的需求和阅读习惯,优化书籍结构,使其易于阅读并具有吸引力。
125 |
126 | ## Rules
127 | 1. 基于用户提供的书籍标题和简介,生成完整的书籍大纲。
128 | 2. 大纲需要包括书籍的主要章节和每一章节的关键内容概述。
129 | 3. 确保大纲的结构合理,内容连贯,有助于推进书籍的主题和情节发展。
130 | 4. 书籍大纲应体现书籍的核心主题,并符合读者的期待。
131 |
132 | ## Goals
133 | 书籍主题:{theme}
134 | 书籍标题和简介:
135 | {intro}
136 |
137 | 撰写书籍大纲(python list 格式,10-20章)
138 | ["第一章:《xxx》xxx", "第二章:《xxx》xxx","...", "xxx"]
139 |
140 | ## Init
141 | 设计合适的章节大纲,只输出 python list内容,此外不要给出任何无关内容和字符。
142 | ```
143 |
144 | (3) 书籍正文内容撰写提示词
145 |
146 | ```
147 | # Role: 书籍写作专家
148 |
149 | ## Profile
150 | - author: LangGPT
151 | - version: 1.0
152 | - language: 中文/英文
153 | - description: 帮助用户根据提供的书籍标题、简介和章节大纲,撰写每一章的具体内容,确保语言风格符合书籍定位,内容连贯、专业、正式。
154 |
155 | ## Skills
156 | 1. 章节内容撰写:能够根据用户提供的章节大纲,撰写完整的章节内容,确保情节发展和主题的深度探讨。
157 | 2. 文体和风格匹配:根据书籍的类型(小说、纪实、学术等)和目标读者,调整写作风格,使其正式、专业且符合书籍定位。
158 | 3. 细节描写与逻辑构建:擅长细节描写,增强故事的真实感与情感深度,保证逻辑严密性。
159 | 4. 内容深化与扩展:在大纲基础上,合理扩展和深化内容,使每一章有足够的丰富性和信息量。
160 |
161 | ## Rules
162 | 1. 依据用户提供的书籍标题、简介和大纲,撰写每一章的详细内容。
163 | 2. 每章内容需符合书籍主题,并在情节、逻辑和语言风格上保持一致。
164 | 3. 确保内容丰富、信息清晰,避免不必要的重复或偏离主题。
165 | 4. 保持正式、专业的语言风格,适合目标读者。
166 | 5. 不需胡说八道,编造事实。
167 |
168 |
169 | ## Goals
170 | 书籍简介:
171 | {book_content}
172 |
173 | 本章大纲:
174 | {chapter_intro}
175 |
176 | 请依据本章大纲和书籍简介撰写本章内容。
177 |
178 | ## OutputFormat:
179 | - 如果需要数学公式,使用写法:"$latex公式$",使其能被 markdown 正确渲染,示例:"$z = \sum_{i=1}^{n} w_i \cdot x_i + b$"。
180 | (注意:你的数学公式不要用 "\[ \]" 写法,这样无法被正确渲染!!!)
181 | - 结构化写作,使用 markdown 格式排版内容。
182 | - 章节标题,示例:"# 第三章:Transformer的基础原理"
183 | - 章节内小标题使用序号, 示例:"## 3.1 Transformer的架构"。
184 | - 合理按需使用粗体,斜体,引用,代码,公式,列表。
185 |
186 | ## Init
187 | 设计合适的章节大纲,只输出本章内容,此外不要给出任何无关内容和字符。
188 | ```
189 |
190 | (4) 使用代码将这些提示词的输入输出串起来
191 |
192 | ```
193 | import os
194 | import re
195 | import json
196 | from typing import List, Dict, Optional, Tuple
197 | from concurrent.futures import ThreadPoolExecutor
198 | from dotenv import load_dotenv
199 | import openai
200 | from phi.assistant import Assistant
201 | from phi.llm.openai import OpenAIChat
202 |
203 | # 加载 .env 文件
204 | load_dotenv()
205 |
206 | def read_prompt(prompt_file: str, replacements: Dict[str, str]) -> str:
207 | """
208 | 读取提示文件并替换占位符
209 | """
210 | with open(prompt_file, 'r', encoding='utf-8') as file:
211 | prompt = file.read()
212 | for key, value in replacements.items():
213 | prompt = prompt.replace(f"{{{key}}}", value)
214 | return prompt
215 | def convert_latex_to_markdown(text):
216 | # 使用正则表达式替换公式开始和结束的 \[ 和 \],但不替换公式内部的
217 | pattern = r'(? str:
240 | # 润色文本
241 | self.assistant = Assistant(
242 | llm=OpenAIChat(model=model_name,
243 | api_key=api_key,
244 | base_url=base_url,
245 | max_tokens=4096, # make it longer to get more context
246 | ),
247 | system_prompt=system_prompt,
248 | prevent_prompt_injection=True,
249 | prevent_hallucinations=False,
250 | # Add functions or Toolkits
251 | #tools=[...],
252 | # Show tool calls in LLM response.
253 | # show_tool_calls=True
254 | )
255 | return self.assistant
256 |
257 | def generate_title_and_intro(self, book_theme, prompt_file = "prompts/title_writer.txt") -> Tuple[str, str]:
258 | """生成书籍标题和主要内容介绍。
259 |
260 | Args:
261 | prompt: 用于生成标题和介绍的提示。
262 |
263 | Returns:
264 | 包含生成的标题和介绍的元组。
265 | """
266 | prompt_args = {"theme": book_theme}
267 | prompt = read_prompt(prompt_file, prompt_args)
268 | #print(prompt)
269 | for attempt in range(3):
270 | try:
271 | response = self.assistant.run(prompt, stream=False)
272 | # convert to json
273 | response = response.strip()
274 | if not response.startswith('{'):
275 | response = '{' + response.split('{', 1)[1]
276 | if not response.endswith('}'):
277 | response = response.split('}', 1)[0] + '}'
278 |
279 | book_title_and_intro = json.loads(response)
280 |
281 | #print(book_title_and_intro)
282 |
283 | return book_title_and_intro
284 | except Exception as e:
285 | print(f"Attempt {attempt + 1} failed: {e}")
286 | return response
287 |
288 | def generate_outline(self, book_theme, book_title_and_intro: str, prompt_file= "prompts/outline_writer.txt") -> List[str]:
289 | """生成书籍章节大纲。
290 |
291 | Args:
292 | prompt: 用于生成大纲的提示。
293 | title: 书籍标题。
294 | intro: 书籍介绍。
295 |
296 | Returns:
297 | 章节标题列表。
298 | """
299 | prompt_args = {"theme": book_theme, "intro": str(book_title_and_intro)}
300 | prompt = read_prompt(prompt_file, prompt_args)
301 | for attempt in range(3):
302 | try:
303 | response = self.assistant.run(prompt, stream=False)
304 | #print(response)
305 | # convert to json
306 | response = response.strip()
307 | if not response.startswith('['):
308 | response = '[' + response.split('[', 1)[1]
309 | if not response.endswith(']'):
310 | response = response.split(']', 1)[0] + ']'
311 | chapters = json.loads(response.strip())
312 | #print(chapters)
313 | return chapters
314 | except Exception as e:
315 | print(f"Attempt {attempt + 1} failed: {e}")
316 | return response
317 |
318 | def generate_chapter(self, book_content, chapter_intro, prompt_file= "prompts/chapter_writer.txt") -> str:
319 | """生成单个章节的内容。
320 |
321 | Args:
322 | chapter_title: 章节标题。
323 | book_title: 书籍标题。
324 | book_intro: 书籍介绍。
325 | outline: 完整的章节大纲。
326 | prompt: 用于生成章节的提示。
327 |
328 | Returns:
329 | 生成的章节内容。
330 | """
331 |
332 | prompt_args = {"book_content": str(book_content), "chapter_intro": str(chapter_intro)}
333 | prompt = read_prompt(prompt_file, prompt_args)
334 | for attempt in range(3):
335 | try:
336 | response = self.assistant.run(prompt, stream=False)
337 | response.strip()
338 | if response.startswith('```markdown'):
339 | # 删除第一行和最后一行
340 | lines = response.splitlines()
341 | response = '\n'.join(lines[1:-1])
342 |
343 | return response
344 | except Exception as e:
345 | print(f"Attempt {attempt + 1} failed: {e}")
346 | response = convert_latex_to_markdown(response)
347 | return response
348 |
349 | def generate_book(self, custom_theme=None, save_file=False) -> None:
350 | """生成整本书并将其保存到文件中。
351 |
352 | Args:
353 | custom_prompts: 自定义提示的字典。可以包括 'title_intro', 'outline' 和 'chapter' 键。
354 | """
355 |
356 | print("开始生成书籍标题和介绍...")
357 | theme = custom_theme if custom_theme else "Transformer是什么"
358 | title_and_intro = self.generate_title_and_intro(theme)
359 | title = title_and_intro["title"]
360 | print(f"书籍标题和介绍:\n {title_and_intro}")
361 |
362 | print("\n开始生成章节大纲...")
363 | chapters = self.generate_outline(theme, title_and_intro)
364 | print("章节大纲:")
365 | print(chapters)
366 |
367 | book_intro = title_and_intro
368 | book_content = "# " + title
369 |
370 | # 使用线程池来并行生成章节内容
371 | print("\n开始创作正文内容,时间较长(约几分钟)请等待~")
372 | with ThreadPoolExecutor() as executor:
373 | chapter_contents = list(executor.map(self.generate_chapter, [book_intro]*len(chapters), chapters))
374 |
375 | for i, chapter in enumerate(chapters, 1):
376 | print(f"\n正在生成第{i}章:{chapter}")
377 | chapter_content = chapter_contents[i-1].strip() # 获取已生成的章节内容
378 | print(chapter_content)
379 | book_content += f"\n\n{chapter_content}"
380 | print(f"第{i}章已完成。")
381 |
382 | print("\n整本书已生成完毕。")
383 | if save_file:
384 | filename = f"books/{title.replace(' ', '_')}.md"
385 | with open(filename, "w", encoding="utf-8") as f:
386 | f.write(book_content)
387 |
388 | print(f"书籍内容已保存到 {filename} 文件中。")
389 | return book_content
390 |
391 | def main():
392 | """主函数, 演示如何使用BookWriter类。"""
393 | book_theme = input("请输入书籍主题(如 AI 是什么?): ")
394 |
395 | api_key = os.getenv("API_KEY")
396 | base_url = os.getenv("BASE_URL")
397 | model_name = os.getenv("MODEL_NAME")
398 | print(base_url, model_name)
399 | book_writer = BookWriter(api_key, base_url, model_name, system_prompt=None)
400 | book_writer.generate_book(custom_theme=book_theme, save_file=True)
401 |
402 | if __name__ == "__main__":
403 | main()
404 | ```
405 |
406 | #### 2.5 项目优化
407 |
408 | 当前的写书项目只是个小 demo,还存在许多问题,同学们可以试着优化这些问题。一些已知的问题和优化方向:
409 |
410 | 1. 章节正文内容的质量提升。优化内容表达、内容的深度、格式排版等,尤其数学公式的格式和排版。
411 | 2. 各章节内容的连贯性。
412 | 3. 章节正文长度提升。
413 | 4. 让图书图文并茂:使用 mardown 的图片语法配图,或者搭配生图模型生成图片。
414 | 5. 其他你能想到的优化方向。
415 |
416 |
417 |
--------------------------------------------------------------------------------
/docs/L1/Prompt/tasks.md:
--------------------------------------------------------------------------------
1 | # LangGPT结构化提示词编写实践
2 |
3 | ## 基础任务 (完成此任务即完成闯关)
4 |
5 | - 背景问题:近期相关研究指出,在处理特定文本分析任务时,语言模型的表现有时会遇到挑战,例如在分析单词内部的具体字母数量时可能会出现错误。
6 | - 任务要求:利用对提示词的精确设计,引导语言模型正确回答出“strawberry”中有几个字母“r”。完成正确的问答交互并提交截图作为完成凭证。
7 |
8 | 参考答案 (能正确得到答案 3 即可)
9 |
10 |
11 | ## 进阶任务 (闯关不要求完成此任务)
12 |
13 | 任选下面其中1个任务基于LangGPT格式编写提示词 (**优秀学员最少编写两组**),使用[书生·浦语大模型](https://internlm-chat.intern-ai.org.cn/suggestion) 进行对话评测。
14 |
15 |
16 | - 公文写作助手
17 | - 商务邮件沟通
18 | - 温柔女友/男友
19 | - MBTI 性格测试
20 | - 剧本创作助手
21 | - 科幻小说生成
22 |
23 |
24 | ### 达标要求
25 |
26 | 将不使用系统提示的书生浦语大模型作为 baseline 对比,提交的系统提示词要指导LLM表现出比baseline更高的性能,提供对比截图并加以分析说明即可。
27 |
28 | - 更好的文字创作能力(更明显的风格、更优美的文字、更准确的格式、更流畅的对话)
29 | - 更准确的回答能力
30 | - 更准确的流程遵循能力
31 |
32 |
33 | ## 闯关材料提交 (完成任务并且提交材料时为闯关成功)
34 |
35 | - 闯关任务分为基础任务和进阶任务,提交完整的提示词(txt文件)和运行结果截图。评分规则为:提示词逻辑清晰与相应领域的方法论结合,模型能够在使用提示词后输出高质量结果。
36 | - 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
37 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
38 |
--------------------------------------------------------------------------------
/docs/L1/ToolChain/readme.md:
--------------------------------------------------------------------------------
1 | ## 任务
2 |
3 | 观看「本关卡视频」和「[官网](https://internlm.intern-ai.org.cn/)」、「[GitHub(https://github.com/internLM/)」 写一篇关于书生大模型全链路开源开放体系的笔记发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
4 |
5 | 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
6 |
--------------------------------------------------------------------------------
/docs/L1/XTuner/README.md:
--------------------------------------------------------------------------------
1 | # XTuner 微调实践微调
2 |
3 |
4 |
5 | 本文档将介绍 InternLM 个人小助手认知
6 |
7 | ## 写在前面
8 |
9 | 微调内容需要使用 30% A100 才能完成。
10 | 本次实战营的微调内容包括了以下两个部分:
11 | 1. SFT 数据的获取
12 | 2. 使用 [InternLM2.5-7B-Chat](https://huggingface.co/internlm/internlm2_5-7b-chat) 模型微调
13 |
14 | 这节课你会收获:
15 | * 针对业务场景(如特殊自我认知的机器人)的微调能力
16 | * 一个属于自己的语言聊天机器人
17 |
18 | XTuner 文档链接:[XTuner-doc-cn](https://xtuner.readthedocs.io/zh-cn/latest/)
19 |
20 | ## 环境配置与数据准备
21 |
22 | 本节中,我们将演示如何安装 XTuner。
23 | 推荐使用 Python-3.10 的 conda 虚拟环境安装 XTuner。
24 |
25 | ### **步骤 0.** 使用 conda 先构建一个 Python-3.10 的虚拟环境
26 |
27 | ```shell
28 | cd ~
29 | #git clone 本repo
30 | git clone https://github.com/InternLM/Tutorial.git -b camp4
31 | mkdir -p /root/finetune && cd /root/finetune
32 | conda create -n xtuner-env python=3.10 -y
33 | conda activate xtuner-env
34 | ```
35 | ### **步骤 1.** 安装 XTuner
36 | 此处推荐用我 freeze 的 requirements.txt,更多的安装方法请回到前面看 XTuner 文档
37 |
38 | ```shell
39 | cd /root/Tutorial/docs/L1/XTuner
40 | pip install -r requirements.txt
41 | ```
42 |
43 |
44 | 如果安装过程出现错误,请参考以下解决方案:
45 | > WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1007)'))': /pypi/simple/bitsandbytes/
46 |
47 | > Could not fetch URL https://mirrors.aliyun.com/pypi/simple/bitsandbytes/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='mirrors.aliyun.com', port=443): Max retries exceeded with url: /pypi/simple/bitsandbytes/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1007)'))) - skipping
48 |
49 | > INFO: pip is looking at multiple versions of xtuner to determine which version is compatible with other requirements. This could take a while.
50 |
51 | > ERROR: Could not find a version that satisfies the requirement bitsandbytes>=0.40.0.post4 (from xtuner) (from versions: none),可以 `Ctrl + C` 退出后换成 `pip install --trusted-host mirrors.aliyun.com -e '.[deepspeed]' -i https://mirrors.aliyun.com/pypi/simple/`
52 |
53 |
54 |
55 |
56 | ### 验证安装
57 | 为了验证 XTuner 是否安装正确,我们将使用命令打印配置文件。
58 |
59 | **打印配置文件:** 在命令行中使用 `xtuner list-cfg` 验证是否能打印配置文件列表。
60 | ```shell
61 | xtuner list-cfg
62 | ```
63 |
64 |
65 | 输出没有报错则为此结果
66 |
67 | xtuner list-cfg
68 | ==========================CONFIGS===========================
69 | baichuan2_13b_base_full_custom_pretrain_e1
70 | baichuan2_13b_base_qlora_alpaca_e3
71 | baichuan2_13b_base_qlora_alpaca_enzh_e3
72 | baichuan2_13b_base_qlora_alpaca_enzh_oasst1_e3
73 | ...
74 | internlm2_1_8b_full_alpaca_e3
75 | internlm2_1_8b_full_custom_pretrain_e1
76 | internlm2_1_8b_qlora_alpaca_e3
77 | internlm2_20b_full_custom_pretrain_e1
78 | internlm2_20b_full_finetune_custom_dataset_e1
79 | internlm2_20b_qlora_alpaca_e3
80 | internlm2_20b_qlora_arxiv_gentitle_e3
81 | internlm2_20b_qlora_code_alpaca_e3
82 | internlm2_20b_qlora_colorist_e5
83 | internlm2_20b_qlora_lawyer_e3
84 | internlm2_20b_qlora_msagent_react_e3_gpu8
85 | internlm2_20b_qlora_oasst1_512_e3
86 | internlm2_20b_qlora_oasst1_e3
87 | internlm2_20b_qlora_sql_e3
88 | internlm2_5_chat_20b_alpaca_e3
89 | internlm2_5_chat_20b_qlora_alpaca_e3
90 | internlm2_5_chat_7b_full_finetune_custom_dataset_e1
91 | internlm2_5_chat_7b_qlora_alpaca_e3
92 | internlm2_5_chat_7b_qlora_oasst1_e3
93 | internlm2_7b_full_custom_pretrain_e1
94 | internlm2_7b_full_finetune_custom_dataset_e1
95 | internlm2_7b_full_finetune_custom_dataset_e1_sequence_parallel_4
96 | internlm2_7b_qlora_alpaca_e3
97 | internlm2_7b_qlora_arxiv_gentitle_e3
98 | internlm2_7b_qlora_code_alpaca_e3
99 | internlm2_7b_qlora_colorist_e5
100 | internlm2_7b_qlora_json_e3
101 | internlm2_7b_qlora_lawyer_e3
102 | internlm2_7b_qlora_msagent_react_e3_gpu8
103 | internlm2_7b_qlora_oasst1_512_e3
104 | internlm2_7b_qlora_oasst1_e3
105 | internlm2_7b_qlora_sql_e3
106 | ...
107 |
108 | > 输出内容为 XTuner 支持微调的模型
109 |
110 |
111 |
112 | ## 修改提供的数据
113 |
114 | ### **步骤 0.** 创建一个新的文件夹用于存储微调数据
115 | ```shell
116 | mkdir -p /root/finetune/data && cd /root/finetune/data
117 | cp -r /root/Tutorial/data/assistant_Tuner.jsonl /root/finetune/data
118 | ```
119 |
120 |
121 | 此时 `finetune` 文件夹下应该有如下结构
122 |
123 | ```sh
124 | finetune
125 | ├── data
126 | │ └── assistant_Tuner.jsonl
127 | └── xtuner
128 | ```
129 |
130 |
131 |
132 | ### **步骤 1.** 创建修改脚本
133 |
134 | 我们写一个脚本生成修改我们需要的微调训练数据,在当前目录下创建一个 `change_script.py` 文件,内容如下:
135 |
136 | ```bash
137 | # 创建 `change_script.py` 文件
138 | touch /root/finetune/data/change_script.py
139 | ```
140 |
141 | 打开该`change_script.py`文件后将下面的内容复制进去。
142 |
143 | ```python
144 | import json
145 | import argparse
146 | from tqdm import tqdm
147 |
148 | def process_line(line, old_text, new_text):
149 | # 解析 JSON 行
150 | data = json.loads(line)
151 |
152 | # 递归函数来处理嵌套的字典和列表
153 | def replace_text(obj):
154 | if isinstance(obj, dict):
155 | return {k: replace_text(v) for k, v in obj.items()}
156 | elif isinstance(obj, list):
157 | return [replace_text(item) for item in obj]
158 | elif isinstance(obj, str):
159 | return obj.replace(old_text, new_text)
160 | else:
161 | return obj
162 |
163 | # 处理整个 JSON 对象
164 | processed_data = replace_text(data)
165 |
166 | # 将处理后的对象转回 JSON 字符串
167 | return json.dumps(processed_data, ensure_ascii=False)
168 |
169 | def main(input_file, output_file, old_text, new_text):
170 | with open(input_file, 'r', encoding='utf-8') as infile, \
171 | open(output_file, 'w', encoding='utf-8') as outfile:
172 |
173 | # 计算总行数用于进度条
174 | total_lines = sum(1 for _ in infile)
175 | infile.seek(0) # 重置文件指针到开头
176 |
177 | # 使用 tqdm 创建进度条
178 | for line in tqdm(infile, total=total_lines, desc="Processing"):
179 | processed_line = process_line(line.strip(), old_text, new_text)
180 | outfile.write(processed_line + '\n')
181 |
182 | if __name__ == "__main__":
183 | parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
184 | parser.add_argument("input_file", help="Input JSONL file to process")
185 | parser.add_argument("output_file", help="Output file for processed JSONL")
186 | parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
187 | parser.add_argument("--new_text", default="闻星", help="Text to replace with")
188 | args = parser.parse_args()
189 |
190 | main(args.input_file, args.output_file, args.old_text, args.new_text)
191 | ```
192 |
193 | 然后修改如下:
194 | 打开 `change_script.py` ,修改 `--new_text` 中 `default="闻星"` 为你的名字。
195 |
196 | ```diff
197 | if __name__ == "__main__":
198 |
199 | parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
200 |
201 | parser.add_argument("input_file", help="Input JSONL file to process")
202 |
203 | parser.add_argument("output_file", help="Output file for processed JSONL")
204 |
205 | parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
206 | - parser.add_argument("--new_text", default="闻星", help="Text to replace with")
207 | + parser.add_argument("--new_text", default="你的名字", help="Text to replace with")
208 |
209 | args = parser.parse_args()
210 | ```
211 |
212 |
213 | ### **步骤 2.** 执行脚本
214 |
215 | ```shell
216 | # usage:python change_script.py {input_file.jsonl} {output_file.jsonl}
217 | cd ~/finetune/data
218 | python change_script.py ./assistant_Tuner.jsonl ./assistant_Tuner_change.jsonl
219 | ```
220 |
221 | `assistant_Tuner_change.jsonl` 是修改后符合 XTuner 格式的训练数据。
222 |
223 |
224 |
225 |
226 | 此时 data 文件夹下应该有如下结构
227 |
228 | ```
229 | |-- /finetune/data/
230 | |-- assistant_Tuner.jsonl
231 | |-- assistant_Tuner_change.jsonl
232 | ```
233 |
234 |
235 |
236 |
237 | ### **步骤 3.** 查看数据
238 |
239 | ```shell
240 | cat assistant_Tuner_change.jsonl | head -n 3
241 | ```
242 |
243 | 此处结果太长不再展示,主要是检查自己要修改的名字是否在数据中。
244 |
245 | ## 训练启动
246 | ### **步骤 0.** 复制模型
247 |
248 | 在InternStudio开发机中的已经提供了微调模型,可以直接软链接即可。
249 |
250 | 本模型位于/root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat
251 |
252 | ```shell
253 | mkdir /root/finetune/models
254 |
255 | ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/finetune/models/internlm2_5-7b-chat
256 | ```
257 |
258 | ### **步骤 1.** 修改 Config
259 |
260 | 获取官方写好的 config
261 | ```shell
262 | # cd {path/to/finetune}
263 | cd /root/finetune
264 | mkdir ./config
265 | cd config
266 | xtuner copy-cfg internlm2_5_chat_7b_qlora_alpaca_e3 ./
267 | ```
268 | 修改以下几行
269 |
270 | ```diff
271 | #######################################################################
272 | # PART 1 Settings #
273 | #######################################################################
274 | - pretrained_model_name_or_path = 'internlm/internlm2_5-7b-chat'
275 | + pretrained_model_name_or_path = '/root/finetune/models/internlm2_5-7b-chat'
276 |
277 | - alpaca_en_path = 'tatsu-lab/alpaca'
278 | + alpaca_en_path = '/root/finetune/data/assistant_Tuner_change.jsonl'
279 |
280 |
281 | evaluation_inputs = [
282 | - '请给我介绍五个上海的景点', 'Please tell me five scenic spots in Shanghai'
283 | + '请介绍一下你自己', 'Please introduce yourself'
284 | ]
285 |
286 | #######################################################################
287 | # PART 3 Dataset & Dataloader #
288 | #######################################################################
289 | alpaca_en = dict(
290 | type=process_hf_dataset,
291 | - dataset=dict(type=load_dataset, path=alpaca_en_path),
292 | + dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
293 | tokenizer=tokenizer,
294 | max_length=max_length,
295 | - dataset_map_fn=alpaca_map_fn,
296 | + dataset_map_fn=None,
297 | template_map_fn=dict(
298 | type=template_map_fn_factory, template=prompt_template),
299 | remove_unused_columns=True,
300 | shuffle_before_pack=True,
301 | pack_to_max_length=pack_to_max_length,
302 | use_varlen_attn=use_varlen_attn)
303 | ```
304 |
305 | 除此之外,我们还可以对一些重要的参数进行调整,包括学习率(lr)、训练的轮数(max_epochs)等等。
306 |
307 |
308 | 常用参数介绍
309 |
310 | | 参数名 | 解释 |
311 | | -------------------------- | ------------------------------------------------------------ |
312 | | **data_path** | 数据路径或 HuggingFace 仓库名 |
313 | | **max_length** | 单条数据最大 Token 数,超过则截断 |
314 | | **pack_to_max_length** | 是否将多条短数据拼接到 max_length,提高 GPU 利用率 |
315 | | **accumulative_counts** | 梯度累积,每多少次 backward 更新一次参数 |
316 | | **sequence_parallel_size** | 并行序列处理的大小,用于模型训练时的序列并行 |
317 | | **batch_size** | 每个设备上的批量大小 |
318 | | **dataloader_num_workers** | 数据加载器中工作进程的数量 |
319 | | **max_epochs** | 训练的最大轮数 |
320 | | **optim_type** | 优化器类型,例如 AdamW |
321 | | **lr** | 学习率 |
322 | | **betas** | 优化器中的 beta 参数,控制动量和平方梯度的移动平均 |
323 | | **weight_decay** | 权重衰减系数,用于正则化和避免过拟合 |
324 | | **max_norm** | 梯度裁剪的最大范数,用于防止梯度爆炸 |
325 | | **warmup_ratio** | 预热的比例,学习率在这个比例的训练过程中线性增加到初始学习率 |
326 | | **save_steps** | 保存模型的步数间隔 |
327 | | **save_total_limit** | 保存的模型总数限制,超过限制时删除旧的模型文件 |
328 | | **prompt_template** | 模板提示,用于定义生成文本的格式或结构 |
329 | | ...... | ...... |
330 |
331 | > 如果想充分利用显卡资源,可以将 `max_length` 和 `batch_size` 这两个参数调大。
332 | ⚠但需要注意的是,在训练 chat 模型时调节参数 `batch_size` 有可能会影响对话模型的效果。
333 |
334 |
335 |
336 |
337 | 本教程已经将改好的 config 放在了 `~/Tutorial/configs/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py` 同学们可以直接使用(前置步骤路径一致的情况下)
338 |
339 |
340 | ### **步骤 2.** 启动微调
341 |
342 | 完成了所有的准备工作后,我们就可以正式的开始我们下一阶段的旅程:XTuner 启动~!
343 |
344 | 当我们准备好了所有内容,我们只需要将使用 `xtuner train` 命令令即可开始训练。
345 |
346 | > `xtuner train` 命令用于启动模型微调进程。该命令需要一个参数:`CONFIG` 用于指定微调配置文件。这里我们使用修改好的配置文件 `internlm2_5_chat_7b_qlora_alpaca_e3_copy.py`。
347 | > 训练过程中产生的所有文件,包括日志、配置文件、检查点文件、微调后的模型等,默认保存在 `work_dirs` 目录下,我们也可以通过添加 `--work-dir` 指定特定的文件保存位置。`--deepspeed` 则为使用 deepspeed, deepspeed 可以节约显存。
348 |
349 | 运行命令进行微调
350 |
351 | ```shell
352 | cd /root/finetune
353 | conda activate xtuner-env
354 |
355 | xtuner train ./config/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py --deepspeed deepspeed_zero2 --work-dir ./work_dirs/assistTuner
356 | ```
357 |
358 | ### **步骤 3.** 权重转换
359 |
360 | 模型转换的本质其实就是将原本使用 Pytorch 训练出来的模型权重文件转换为目前通用的 HuggingFace 格式文件,那么我们可以通过以下命令来实现一键转换。
361 |
362 | 我们可以使用 `xtuner convert pth_to_hf` 命令来进行模型格式转换。
363 |
364 | > `xtuner convert pth_to_hf` 命令用于进行模型格式转换。该命令需要三个参数:`CONFIG` 表示微调的配置文件, `PATH_TO_PTH_MODEL` 表示微调的模型权重文件路径,即要转换的模型权重, `SAVE_PATH_TO_HF_MODEL` 表示转换后的 HuggingFace 格式文件的保存路径。
365 |
366 | 除此之外,我们其实还可以在转换的命令中添加几个额外的参数,包括:
367 |
368 | | 参数名 | 解释 |
369 | | --------------------- | -------------------------------------------- |
370 | | --fp32 | 代表以fp32的精度开启,假如不输入则默认为fp16 |
371 | | --max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
372 |
373 |
374 | ```bash
375 | cd /root/finetune/work_dirs/assistTuner
376 |
377 | conda activate xtuner-env
378 |
379 | # 先获取最后保存的一个pth文件
380 | pth_file=`ls -t /root/finetune/work_dirs/assistTuner/*.pth | head -n 1 | sed 's/:$//'`
381 | export MKL_SERVICE_FORCE_INTEL=1
382 | export MKL_THREADING_LAYER=GNU
383 | xtuner convert pth_to_hf ./internlm2_5_chat_7b_qlora_alpaca_e3_copy.py ${pth_file} ./hf
384 | ```
385 |
386 | 模型格式转换完成后,我们的目录结构应该是这样子的。
387 |
388 |
389 | 目录结构
390 |
391 | ```
392 | ├── hf
393 | │ ├── README.md
394 | │ ├── adapter_config.json
395 | │ ├── adapter_model.bin
396 | │ └── xtuner_config.py
397 | ```
398 |
399 |
400 |
401 | 转换完成后,可以看到模型被转换为 HuggingFace 中常用的 .bin 格式文件,这就代表着文件成功被转化为 HuggingFace 格式了。
402 |
403 | 此时,hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”
404 |
405 | > 可以简单理解:LoRA 模型文件 = Adapter
406 |
407 | ### **步骤 4.** 模型合并
408 |
409 | 对于 LoRA 或者 QLoRA 微调出来的模型其实并不是一个完整的模型,而是一个额外的层(Adapter),训练完的这个层最终还是要与原模型进行合并才能被正常的使用。
410 |
411 | > 对于全量微调的模型(full)其实是不需要进行整合这一步的,因为全量微调修改的是原模型的权重而非微调一个新的 Adapter ,因此是不需要进行模型整合的。
412 |
413 | 在 XTuner 中提供了一键合并的命令 `xtuner convert merge`,在使用前我们需要准备好三个路径,包括原模型的路径、训练好的 Adapter 层的(模型格式转换后的)路径以及最终保存的路径。
414 |
415 | > `xtuner convert merge`命令用于合并模型。该命令需要三个参数:`LLM` 表示原模型路径,`ADAPTER` 表示 Adapter 层的路径, `SAVE_PATH` 表示合并后的模型最终的保存路径。
416 |
417 | 在模型合并这一步还有其他很多的可选参数,包括:
418 |
419 | | 参数名 | 解释 |
420 | | ---------------------- | ------------------------------------------------------------ |
421 | | --max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
422 | | --device {device_name} | 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
423 | | --is-clip | 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
424 |
425 |
426 | ```bash
427 | cd /root/finetune/work_dirs/assistTuner
428 | conda activate xtuner-env
429 |
430 | export MKL_SERVICE_FORCE_INTEL=1
431 | export MKL_THREADING_LAYER=GNU
432 | xtuner convert merge /root/finetune/models/internlm2_5-7b-chat ./hf ./merged --max-shard-size 2GB
433 | ```
434 |
435 | 模型合并完成后,我们的目录结构应该是这样子的。
436 |
437 |
438 | 目录结构
439 |
440 | ```
441 | ├── merged
442 | │ ├── README.md
443 | │ ├── config.json
444 | │ ├── configuration.json
445 | │ ├── configuration_internlm2.py
446 | │ ├── generation_config.json
447 | │ ├── modeling_internlm2.py
448 | │ ├── pytorch_model-00001-of-00008.bin
449 | │ ├── pytorch_model-00002-of-00008.bin
450 | │ ├── pytorch_model-00003-of-00008.bin
451 | │ ├── pytorch_model-00004-of-00008.bin
452 | │ ├── pytorch_model-00005-of-00008.bin
453 | │ ├── pytorch_model-00006-of-00008.bin
454 | │ ├── pytorch_model-00007-of-00008.bin
455 | │ ├── pytorch_model-00008-of-00008.bin
456 | │ ├── pytorch_model.bin.index.json
457 | │ ├── special_tokens_map.json
458 | │ ├── tokenization_internlm2.py
459 | │ ├── tokenization_internlm2_fast.py
460 | │ ├── tokenizer.json
461 | │ ├── tokenizer.model
462 | │ └── tokenizer_config.json
463 | ```
464 |
465 |
466 |
467 | 在模型合并完成后,我们就可以看到最终的模型和原模型文件夹非常相似,包括了分词器、权重文件、配置信息等等。
468 |
469 | ## 模型 WebUI 对话
470 |
471 | 微调完成后,我们可以再次运行 `xtuner_streamlit_demo.py` 脚本来观察微调后的对话效果,不过在运行之前,我们需要将脚本中的模型路径修改为微调后的模型的路径。
472 |
473 | ```shell
474 | cd ~/Tutorial/tools/L1_XTuner_code
475 | ```
476 |
477 | ```diff
478 | # 直接修改脚本文件第18行
479 | - model_name_or_path = "Shanghai_AI_Laboratory/internlm2_5-7b-chat"
480 | + model_name_or_path = "/root/finetune/work_dirs/assistTuner/merged"
481 | ```
482 |
483 | 然后,我们可以直接启动应用。
484 |
485 |
486 | ```bash
487 | conda activate xtuner-env
488 |
489 | pip install streamlit==1.31.0
490 | streamlit run /root/Tutorial/tools/L1_XTuner_code/xtuner_streamlit_demo.py
491 | ```
492 |
493 | 运行后,确保端口映射正常,如果映射已断开则需要重新做一次端口映射。
494 |
495 |
496 | ```bash
497 | ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p *****
498 | ```
499 |
500 | 最后,通过浏览器访问:http://127.0.0.1:8501 来进行对话了。
501 |
502 | 
503 |
504 |
--------------------------------------------------------------------------------
/docs/L1/XTuner/easy_README.md:
--------------------------------------------------------------------------------
1 | # XTuner 微调实践微调 (本文档已废弃)
2 |
3 |
4 |
5 | 本文档将介绍 InternLM 个人小助手认知
6 |
7 | **本文档为有一定基础可以快速上手的同学准备,比`README.md`的说明更加简洁。**
8 |
9 | ## 写在前面
10 |
11 | 微调内容需要使用 30% A100 才能完成。
12 | 本次实战营的微调内容包括了以下两个部分:
13 | 1. SFT 数据的获取
14 | 2. 使用 [InternLM2.5-7B-Chat](https://huggingface.co/internlm/internlm2_5-7b-chat) 模型微调
15 |
16 | 这节课你会收获:
17 | * 针对业务场景(如特殊自我认知的机器人)的微调能力
18 | * 一个属于自己的语言聊天机器人
19 |
20 | 本节课对应的视频链接:暂无
21 |
22 | XTuner 文档链接:[XTuner-doc-cn](https://xtuner.readthedocs.io/zh-cn/latest/)
23 |
24 | ## 环境配置与数据准备
25 |
26 | 本节中,我们将演示如何安装 XTuner。
27 |
28 | ### **步骤 0.** 使用 conda 激活一个已有的虚拟环境
29 |
30 | ```shell
31 | cd ~
32 | #git clone 本repo
33 | git clone https://github.com/InternLM/Tutorial.git -b camp4
34 | mkdir -p /root/finetune && cd /root/finetune
35 | conda activate /root/share/pre_envs/pytorch2.3.1cu12.1
36 | ```
37 |
38 | ### **步骤 1.** 安装 XTuner
39 | 此处推荐源码安装,更多的安装方法请回到前面看 XTuner 文档
40 |
41 | ```shell
42 | pip install -t /root/finetune/env 'xtuner[deepspeed]' timm==1.0.9 transformers==4.39.0
43 | ```
44 |
45 | 每次使用前,需要运行一下命令,把自定义的安装包的路径添加到PYTHONPATH环境变量中,这样python才能找到你安装的包(同一个终端下只需运行一次):
46 |
47 | ```Bash
48 | export PYTHONPATH=/root/finetune/env:$PYTHONPATH
49 | export PATH=/root/finetune/env/bin:$PATH
50 | ```
51 |
52 | ### 验证安装
53 | 为了验证 XTuner 是否安装正确,我们将使用命令打印配置文件。
54 |
55 | **打印配置文件:** 在命令行中使用 `xtuner list-cfg` 验证是否能打印配置文件列表。
56 | ```shell
57 | xtuner list-cfg
58 | ```
59 |
60 |
61 | 输出没有报错则为此结果
62 |
63 | xtuner list-cfg
64 | ==========================CONFIGS===========================
65 | baichuan2_13b_base_full_custom_pretrain_e1
66 | baichuan2_13b_base_qlora_alpaca_e3
67 | baichuan2_13b_base_qlora_alpaca_enzh_e3
68 | baichuan2_13b_base_qlora_alpaca_enzh_oasst1_e3
69 | ...
70 | internlm2_1_8b_full_alpaca_e3
71 | internlm2_1_8b_full_custom_pretrain_e1
72 | internlm2_1_8b_qlora_alpaca_e3
73 | internlm2_20b_full_custom_pretrain_e1
74 | internlm2_20b_full_finetune_custom_dataset_e1
75 | internlm2_20b_qlora_alpaca_e3
76 | internlm2_20b_qlora_arxiv_gentitle_e3
77 | internlm2_20b_qlora_code_alpaca_e3
78 | internlm2_20b_qlora_colorist_e5
79 | internlm2_20b_qlora_lawyer_e3
80 | internlm2_20b_qlora_msagent_react_e3_gpu8
81 | internlm2_20b_qlora_oasst1_512_e3
82 | internlm2_20b_qlora_oasst1_e3
83 | internlm2_20b_qlora_sql_e3
84 | internlm2_5_chat_20b_alpaca_e3
85 | internlm2_5_chat_20b_qlora_alpaca_e3
86 | internlm2_5_chat_7b_full_finetune_custom_dataset_e1
87 | internlm2_5_chat_7b_qlora_alpaca_e3
88 | internlm2_5_chat_7b_qlora_oasst1_e3
89 | internlm2_7b_full_custom_pretrain_e1
90 | internlm2_7b_full_finetune_custom_dataset_e1
91 | internlm2_7b_full_finetune_custom_dataset_e1_sequence_parallel_4
92 | internlm2_7b_qlora_alpaca_e3
93 | internlm2_7b_qlora_arxiv_gentitle_e3
94 | internlm2_7b_qlora_code_alpaca_e3
95 | internlm2_7b_qlora_colorist_e5
96 | internlm2_7b_qlora_json_e3
97 | internlm2_7b_qlora_lawyer_e3
98 | internlm2_7b_qlora_msagent_react_e3_gpu8
99 | internlm2_7b_qlora_oasst1_512_e3
100 | internlm2_7b_qlora_oasst1_e3
101 | internlm2_7b_qlora_sql_e3
102 | ...
103 |
104 | > 输出内容为 XTuner 支持微调的模型
105 |
106 |
107 |
108 | ## 修改提供的数据
109 |
110 | ### **步骤 0.** 创建一个新的文件夹用于存储微调数据
111 | ```shell
112 | mkdir -p /root/finetune/data && cd /root/finetune/data
113 | cp -r /root/Tutorial/data/assistant_Tuner.jsonl /root/finetune/data
114 | ```
115 |
116 |
117 | 此时 `finetune` 文件夹下应该有如下结构
118 |
119 | ```sh
120 | finetune
121 | ├── data
122 | │ └── assistant_Tuner.jsonl
123 | └── xtuner
124 | ```
125 |
126 |
127 |
128 | ### **步骤 1.** 创建修改脚本
129 |
130 | 我们写一个脚本生成修改我们需要的微调训练数据,在当前目录下创建一个 `change_script.py` 文件,内容如下:
131 |
132 | ```bash
133 | # 创建 `change_script.py` 文件
134 | touch /root/finetune/data/change_script.py
135 | ```
136 |
137 | 打开该`change_script.py`文件后将下面的内容复制进去。
138 |
139 | ```python
140 | import json
141 | import argparse
142 | from tqdm import tqdm
143 |
144 | def process_line(line, old_text, new_text):
145 | # 解析 JSON 行
146 | data = json.loads(line)
147 |
148 | # 递归函数来处理嵌套的字典和列表
149 | def replace_text(obj):
150 | if isinstance(obj, dict):
151 | return {k: replace_text(v) for k, v in obj.items()}
152 | elif isinstance(obj, list):
153 | return [replace_text(item) for item in obj]
154 | elif isinstance(obj, str):
155 | return obj.replace(old_text, new_text)
156 | else:
157 | return obj
158 |
159 | # 处理整个 JSON 对象
160 | processed_data = replace_text(data)
161 |
162 | # 将处理后的对象转回 JSON 字符串
163 | return json.dumps(processed_data, ensure_ascii=False)
164 |
165 | def main(input_file, output_file, old_text, new_text):
166 | with open(input_file, 'r', encoding='utf-8') as infile, \
167 | open(output_file, 'w', encoding='utf-8') as outfile:
168 |
169 | # 计算总行数用于进度条
170 | total_lines = sum(1 for _ in infile)
171 | infile.seek(0) # 重置文件指针到开头
172 |
173 | # 使用 tqdm 创建进度条
174 | for line in tqdm(infile, total=total_lines, desc="Processing"):
175 | processed_line = process_line(line.strip(), old_text, new_text)
176 | outfile.write(processed_line + '\n')
177 |
178 | if __name__ == "__main__":
179 | parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
180 | parser.add_argument("input_file", help="Input JSONL file to process")
181 | parser.add_argument("output_file", help="Output file for processed JSONL")
182 | parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
183 | parser.add_argument("--new_text", default="机智流", help="Text to replace with")
184 | args = parser.parse_args()
185 |
186 | main(args.input_file, args.output_file, args.old_text, args.new_text)
187 | ```
188 |
189 | 然后修改如下:
190 | 打开 `change_script.py` ,修改 `--new_text` 中 `default="机智流"` 为你的名字。
191 |
192 | ```diff
193 | if __name__ == "__main__":
194 |
195 | parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
196 |
197 | parser.add_argument("input_file", help="Input JSONL file to process")
198 |
199 | parser.add_argument("output_file", help="Output file for processed JSONL")
200 |
201 | parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
202 | - parser.add_argument("--new_text", default="机智流", help="Text to replace with")
203 | + parser.add_argument("--new_text", default="你的名字", help="Text to replace with")
204 |
205 | args = parser.parse_args()
206 | ```
207 |
208 |
209 | ### **步骤 2.** 执行脚本
210 |
211 | ```shell
212 | # usage:python change_script.py {input_file.jsonl} {output_file.jsonl}
213 |
214 | cd ~/finetune/data
215 | python change_script.py ./assistant_Tuner.jsonl ./assistant_Tuner_change.jsonl
216 | ```
217 |
218 | `assistant_Tuner_change.jsonl` 是修改后符合 XTuner 格式的训练数据。
219 |
220 |
221 |
222 | 此时 data 文件夹下应该有如下结构
223 |
224 | ```
225 | |-- /finetune/data/
226 | |-- assistant_Tuner.jsonl
227 | |-- assistant_Tuner_change.jsonl
228 | ```
229 |
230 |
231 |
232 |
233 | ### **步骤 3.** 查看数据
234 |
235 | ```shell
236 | cat assistant_Tuner_change.jsonl | head -n 3
237 | ```
238 | 此处结果太长不再展示,主要是检查自己要修改的名字是否在数据中。
239 |
240 | ## 训练启动
241 | ### **步骤 0.** 复制模型
242 |
243 | 在InternStudio开发机中的已经提供了微调模型,可以直接软链接即可。
244 |
245 | 本模型位于/root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat
246 |
247 | ```shell
248 | mkdir /root/finetune/models
249 | ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/finetune/models/internlm2_5-7b-chat
250 |
251 | ```
252 |
253 | ### **步骤 1.** 修改 Config
254 |
255 | 获取官方写好的 config
256 | ```shell
257 | # cd {path/to/finetune}
258 | cd /root/finetune
259 | mkdir ./config
260 | cd config
261 | xtuner copy-cfg internlm2_5_chat_7b_qlora_alpaca_e3 ./
262 | ```
263 | 修改以下几行
264 |
265 | ```diff
266 | #######################################################################
267 | # PART 1 Settings #
268 | #######################################################################
269 | - pretrained_model_name_or_path = 'internlm2_5-7b-chat'
270 | + pretrained_model_name_or_path = '/root/finetune/models/internlm2_5-7b-chat'
271 |
272 | - alpaca_en_path = 'tatsu-lab/alpaca'
273 | + alpaca_en_path = '/root/finetune/data/assist_Tuner_change.jsonl'
274 |
275 | evaluation_inputs = [
276 | - '请给我介绍五个上海的景点', 'Please tell me five scenic spots in Shanghai'
277 | + '请介绍一下你自己', 'Please introduce yourself'
278 | ]
279 |
280 | #######################################################################
281 | # PART 3 Dataset & Dataloader #
282 | #######################################################################
283 | alpaca_en = dict(
284 | type=process_hf_dataset,
285 | - dataset=dict(type=load_dataset, path=alpaca_en_path),
286 | + dataset=dict(type=load_dataset, path='json', data_files=dict(train=alpaca_en_path)),
287 | tokenizer=tokenizer,
288 | max_length=max_length,
289 | - dataset_map_fn=alpaca_map_fn,
290 | + dataset_map_fn=None,
291 | template_map_fn=dict(
292 | type=template_map_fn_factory, template=prompt_template),
293 | remove_unused_columns=True,
294 | shuffle_before_pack=True,
295 | pack_to_max_length=pack_to_max_length,
296 | use_varlen_attn=use_varlen_attn)
297 | ```
298 |
299 | 除此之外,我们还可以对一些重要的参数进行调整,包括学习率(lr)、训练的轮数(max_epochs)等等。
300 |
301 |
302 | 常用参数介绍
303 |
304 | | 参数名 | 解释 |
305 | | -------------------------- | ------------------------------------------------------------ |
306 | | **data_path** | 数据路径或 HuggingFace 仓库名 |
307 | | **max_length** | 单条数据最大 Token 数,超过则截断 |
308 | | **pack_to_max_length** | 是否将多条短数据拼接到 max_length,提高 GPU 利用率 |
309 | | **accumulative_counts** | 梯度累积,每多少次 backward 更新一次参数 |
310 | | **sequence_parallel_size** | 并行序列处理的大小,用于模型训练时的序列并行 |
311 | | **batch_size** | 每个设备上的批量大小 |
312 | | **dataloader_num_workers** | 数据加载器中工作进程的数量 |
313 | | **max_epochs** | 训练的最大轮数 |
314 | | **optim_type** | 优化器类型,例如 AdamW |
315 | | **lr** | 学习率 |
316 | | **betas** | 优化器中的 beta 参数,控制动量和平方梯度的移动平均 |
317 | | **weight_decay** | 权重衰减系数,用于正则化和避免过拟合 |
318 | | **max_norm** | 梯度裁剪的最大范数,用于防止梯度爆炸 |
319 | | **warmup_ratio** | 预热的比例,学习率在这个比例的训练过程中线性增加到初始学习率 |
320 | | **save_steps** | 保存模型的步数间隔 |
321 | | **save_total_limit** | 保存的模型总数限制,超过限制时删除旧的模型文件 |
322 | | **prompt_template** | 模板提示,用于定义生成文本的格式或结构 |
323 | | ...... | ...... |
324 |
325 | > 如果想充分利用显卡资源,可以将 `max_length` 和 `batch_size` 这两个参数调大。
326 | ⚠但需要注意的是,在训练 chat 模型时调节参数 `batch_size` 有可能会影响对话模型的效果。
327 |
328 |
329 |
330 |
331 | 本教程已经将改好的 config 放在了 `~/Tutorial/configs/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py` 同学们可以直接使用(前置步骤路径一致的情况下)
332 |
333 |
334 | ### **步骤 2.** 启动微调
335 |
336 | 完成了所有的准备工作后,我们就可以正式的开始我们下一阶段的旅程:XTuner 启动~!
337 |
338 | 当我们准备好了所有内容,我们只需要将使用 `xtuner train` 命令令即可开始训练。
339 |
340 | > `xtuner train` 命令用于启动模型微调进程。该命令需要一个参数:`CONFIG` 用于指定微调配置文件。这里我们使用修改好的配置文件 `internlm2_5_chat_7b_qlora_alpaca_e3_copy.py`。
341 | > 训练过程中产生的所有文件,包括日志、配置文件、检查点文件、微调后的模型等,默认保存在 `work_dirs` 目录下,我们也可以通过添加 `--work-dir` 指定特定的文件保存位置。`--deepspeed` 则为使用 deepspeed, deepspeed 可以节约显存。
342 |
343 | 运行命令进行微调
344 |
345 | ```shell
346 | cd /root/finetune
347 | conda activate /root/share/pre_envs/pytorch2.3.1cu12.1
348 | export PYTHONPATH=/root/finetune/env:$PYTHONPATH
349 | export PATH=/root/finetune/env/bin:$PATH
350 |
351 | xtuner train ./config/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py --deepspeed deepspeed_zero2 --work-dir ./work_dirs/assistTuner
352 | ```
353 |
354 | ### **步骤 3.** 权重转换
355 |
356 | 模型转换的本质其实就是将原本使用 Pytorch 训练出来的模型权重文件转换为目前通用的 HuggingFace 格式文件,那么我们可以通过以下命令来实现一键转换。
357 |
358 | 我们可以使用 `xtuner convert pth_to_hf` 命令来进行模型格式转换。
359 |
360 | > `xtuner convert pth_to_hf` 命令用于进行模型格式转换。该命令需要三个参数:`CONFIG` 表示微调的配置文件, `PATH_TO_PTH_MODEL` 表示微调的模型权重文件路径,即要转换的模型权重, `SAVE_PATH_TO_HF_MODEL` 表示转换后的 HuggingFace 格式文件的保存路径。
361 |
362 | 除此之外,我们其实还可以在转换的命令中添加几个额外的参数,包括:
363 |
364 | | 参数名 | 解释 |
365 | | --------------------- | -------------------------------------------- |
366 | | --fp32 | 代表以fp32的精度开启,假如不输入则默认为fp16 |
367 | | --max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
368 |
369 |
370 | ```bash
371 | cd /root/finetune/work_dirs/assistTuner
372 | conda activate /root/share/pre_envs/pytorch2.3.1cu12.1
373 | export PYTHONPATH=/root/finetune/env:$PYTHONPATH
374 | export PATH=/root/finetune/env/bin:$PATH
375 |
376 | # 先获取最后保存的一个pth文件
377 | pth_file=`ls -t /root/finetune/work_dirs/assistTuner/*.pth | head -n 1 | sed 's/:$//'`
378 | export MKL_SERVICE_FORCE_INTEL=1
379 | export MKL_THREADING_LAYER=GNU
380 |
381 | xtuner convert pth_to_hf ./config/internlm2_5_chat_7b_qlora_alpaca_e3_copy.py ${pth_file} ./hf
382 | ```
383 |
384 | 模型格式转换完成后,我们的目录结构应该是这样子的。
385 |
386 |
387 | 目录结构
388 |
389 | ```
390 | ├── hf
391 | │ ├── README.md
392 | │ ├── adapter_config.json
393 | │ ├── adapter_model.bin
394 | │ └── xtuner_config.py
395 | ```
396 |
397 |
398 |
399 | 转换完成后,可以看到模型被转换为 HuggingFace 中常用的 .bin 格式文件,这就代表着文件成功被转化为 HuggingFace 格式了。
400 |
401 | 此时,hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”
402 |
403 | > 可以简单理解:LoRA 模型文件 = Adapter
404 |
405 | ### **步骤 4.** 模型合并
406 |
407 | 对于 LoRA 或者 QLoRA 微调出来的模型其实并不是一个完整的模型,而是一个额外的层(Adapter),训练完的这个层最终还是要与原模型进行合并才能被正常的使用。
408 |
409 | > 对于全量微调的模型(full)其实是不需要进行整合这一步的,因为全量微调修改的是原模型的权重而非微调一个新的 Adapter ,因此是不需要进行模型整合的。
410 |
411 | 在 XTuner 中提供了一键合并的命令 `xtuner convert merge`,在使用前我们需要准备好三个路径,包括原模型的路径、训练好的 Adapter 层的(模型格式转换后的)路径以及最终保存的路径。
412 |
413 | > `xtuner convert merge`命令用于合并模型。该命令需要三个参数:`LLM` 表示原模型路径,`ADAPTER` 表示 Adapter 层的路径, `SAVE_PATH` 表示合并后的模型最终的保存路径。
414 |
415 | 在模型合并这一步还有其他很多的可选参数,包括:
416 |
417 | | 参数名 | 解释 |
418 | | ---------------------- | ------------------------------------------------------------ |
419 | | --max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
420 | | --device {device_name} | 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
421 | | --is-clip | 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
422 |
423 |
424 | ```bash
425 | cd /root/finetune/work_dirs/assistTuner
426 | conda activate /root/share/pre_envs/pytorch2.3.1cu12.1
427 | export PYTHONPATH=/root/finetune/env:$PYTHONPATH
428 | export PATH=/root/finetune/env/bin:$PATH
429 |
430 | export MKL_SERVICE_FORCE_INTEL=1
431 | export MKL_THREADING_LAYER=GNU
432 | xtuner convert merge /root/finetune/models/internlm2_5-7b-chat ./hf ./merged --max-shard-size 2GB
433 | ```
434 |
435 | 模型合并完成后,我们的目录结构应该是这样子的。
436 |
437 |
438 | 目录结构
439 |
440 | ```
441 | ├── merged
442 | │ ├── README.md
443 | │ ├── config.json
444 | │ ├── configuration.json
445 | │ ├── configuration_internlm2.py
446 | │ ├── generation_config.json
447 | │ ├── modeling_internlm2.py
448 | │ ├── pytorch_model-00001-of-00008.bin
449 | │ ├── pytorch_model-00002-of-00008.bin
450 | │ ├── pytorch_model-00003-of-00008.bin
451 | │ ├── pytorch_model-00004-of-00008.bin
452 | │ ├── pytorch_model-00005-of-00008.bin
453 | │ ├── pytorch_model-00006-of-00008.bin
454 | │ ├── pytorch_model-00007-of-00008.bin
455 | │ ├── pytorch_model-00008-of-00008.bin
456 | │ ├── pytorch_model.bin.index.json
457 | │ ├── special_tokens_map.json
458 | │ ├── tokenization_internlm2.py
459 | │ ├── tokenization_internlm2_fast.py
460 | │ ├── tokenizer.json
461 | │ ├── tokenizer.model
462 | │ └── tokenizer_config.json
463 | ```
464 |
465 |
466 |
467 | 在模型合并完成后,我们就可以看到最终的模型和原模型文件夹非常相似,包括了分词器、权重文件、配置信息等等。
468 |
469 | ## 模型 WebUI 对话
470 |
471 | 微调完成后,我们可以再次运行 `xtuner_streamlit_demo.py` 脚本来观察微调后的对话效果,不过在运行之前,我们需要将脚本中的模型路径修改为微调后的模型的路径。
472 |
473 | ```shell
474 | cd ~/Tutorial/tools/L1_XTuner_code
475 | ```
476 |
477 | ```diff
478 | # 直接修改脚本文件第18行
479 | - model_name_or_path = "Shanghai_AI_Laboratory/internlm2_5-7b-chat"
480 | + model_name_or_path = "./merged"
481 | ```
482 |
483 | 然后,我们可以直接启动应用。
484 |
485 |
486 | ```bash
487 | conda activate /root/share/pre_envs/pytorch2.3.1cu12.1
488 | export PYTHONPATH=/root/finetune/env:$PYTHONPATH
489 | export PATH=/root/finetune/env/bin:$PATH
490 |
491 | streamlit run /root/Tutorial/tools/L1_XTuner_code/xtuner_streamlit_demo.py
492 | ```
493 |
494 | 运行后,确保端口映射正常,如果映射已断开则需要重新做一次端口映射。
495 |
496 |
497 | ```bash
498 | ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p *****
499 | ```
500 |
501 | 最后,通过浏览器访问:http://127.0.0.1:8501 来进行对话了。
502 |
503 | 
504 |
505 |
--------------------------------------------------------------------------------
/docs/L1/XTuner/requirements.txt:
--------------------------------------------------------------------------------
1 | accelerate==0.27.0
2 | addict==2.4.0
3 | aiohttp==3.9.3
4 | aiosignal==1.3.1
5 | aliyun-python-sdk-core==2.14.0
6 | aliyun-python-sdk-kms==2.16.2
7 | altair==5.2.0
8 | annotated-types==0.6.0
9 | anyio==4.2.0
10 | argon2-cffi==23.1.0
11 | argon2-cffi-bindings==21.2.0
12 | arrow==1.3.0
13 | arxiv==2.1.0
14 | asttokens==2.4.1
15 | async-lru==2.0.4
16 | async-timeout==4.0.3
17 | attrs==23.2.0
18 | Babel==2.14.0
19 | beautifulsoup4==4.12.3
20 | bitsandbytes==0.42.0
21 | bleach==6.1.0
22 | blinker==1.7.0
23 | cachetools==5.3.2
24 | certifi==2024.2.2
25 | cffi==1.16.0
26 | charset-normalizer==3.3.2
27 | click==8.1.7
28 | colorama==0.4.6
29 | comm==0.2.1
30 | contourpy==1.2.0
31 | crcmod==1.7
32 | cryptography==42.0.2
33 | cycler==0.12.1
34 | datasets==2.17.0
35 | debugpy==1.8.1
36 | decorator==5.1.1
37 | deepspeed==0.13.1
38 | defusedxml==0.7.1
39 | dill==0.3.8
40 | distro==1.9.0
41 | einops==0.8.0
42 | einx==0.3.0
43 | et-xmlfile==1.1.0
44 | exceptiongroup==1.2.0
45 | executing==2.0.1
46 | fastapi==0.112.0
47 | fastjsonschema==2.19.1
48 | feedparser==6.0.10
49 | filelock==3.14.0
50 | fonttools==4.48.1
51 | fqdn==1.5.1
52 | frozendict==2.4.4
53 | frozenlist==1.4.1
54 | fsspec==2023.10.0
55 | func-timeout==4.3.5
56 | gast==0.5.4
57 | gitdb==4.0.11
58 | GitPython==3.1.41
59 | google-search-results==2.4.2
60 | griffe==0.40.1
61 | h11==0.14.0
62 | hjson==3.1.0
63 | httpcore==1.0.3
64 | httpx==0.26.0
65 | huggingface-hub==0.24.2
66 | idna==3.6
67 | imageio==2.34.2
68 | importlib-metadata==7.0.1
69 | ipykernel==6.29.2
70 | ipython==8.21.0
71 | ipywidgets==8.1.2
72 | isoduration==20.11.0
73 | jedi==0.19.1
74 | Jinja2==3.1.3
75 | jmespath==0.10.0
76 | json5==0.9.14
77 | jsonpointer==2.4
78 | jsonschema==4.21.1
79 | jsonschema-specifications==2023.12.1
80 | kiwisolver==1.4.5
81 | lagent==0.2.1
82 | lazy_loader==0.4
83 | llvmlite==0.43.0
84 | lxml==5.1.0
85 | markdown-it-py==3.0.0
86 | MarkupSafe==2.1.5
87 | matplotlib==3.8.2
88 | matplotlib-inline==0.1.6
89 | mdurl==0.1.2
90 | mistune==3.0.2
91 | mmengine==0.10.3
92 | modelscope==1.12.0
93 | mpi4py_mpich==3.1.5
94 | mpmath==1.3.0
95 | multidict==6.0.5
96 | multiprocess==0.70.16
97 | nbclient==0.9.0
98 | nbconvert==7.16.0
99 | nbformat==5.9.2
100 | nest-asyncio==1.6.0
101 | networkx==3.2.1
102 | ninja==1.11.1.1
103 | notebook==7.0.8
104 | notebook_shim==0.2.3
105 | numba==0.60.0
106 | numpy==1.26.4
107 | nvidia-cublas-cu12==12.1.3.1
108 | nvidia-cuda-cupti-cu12==12.1.105
109 | nvidia-cuda-nvrtc-cu12==12.1.105
110 | nvidia-cuda-runtime-cu12==12.1.105
111 | nvidia-cudnn-cu12==8.9.2.26
112 | nvidia-cufft-cu12==11.0.2.54
113 | nvidia-curand-cu12==10.3.2.106
114 | nvidia-cusolver-cu12==11.4.5.107
115 | nvidia-cusparse-cu12==12.1.0.106
116 | nvidia-nccl-cu12==2.19.3
117 | nvidia-nvjitlink-cu12==12.3.101
118 | nvidia-nvtx-cu12==12.1.105
119 | openai==1.12.0
120 | opencv-python==4.9.0.80
121 | openpyxl==3.1.2
122 | oss2==2.17.0
123 | overrides==7.7.0
124 | packaging==24.1
125 | pandas==2.2.0
126 | pandocfilters==1.5.1
127 | parso==0.8.3
128 | peft==0.8.2
129 | pexpect==4.9.0
130 | phx-class-registry==4.1.0
131 | pillow==10.2.0
132 | platformdirs==4.2.0
133 | prometheus-client==0.19.0
134 | prompt-toolkit==3.0.43
135 | protobuf==4.25.2
136 | psutil==5.9.8
137 | ptyprocess==0.7.0
138 | pure-eval==0.2.2
139 | py-cpuinfo==9.0.0
140 | pyarrow==15.0.0
141 | pyarrow-hotfix==0.6
142 | pybase16384==0.3.7
143 | pycparser==2.21
144 | pycryptodome==3.20.0
145 | pydantic==2.6.1
146 | pydantic_core==2.16.2
147 | pydeck==0.8.1b0
148 | Pygments==2.17.2
149 | pynvml==11.5.0
150 | pyparsing==3.1.1
151 | python-dateutil==2.8.2
152 | python-json-logger==2.0.7
153 | python-pptx==0.6.23
154 | PyYAML==6.0.1
155 | pyzmq==25.1.2
156 | qtconsole==5.5.1
157 | QtPy==2.4.1
158 | referencing==0.33.0
159 | regex==2023.12.25
160 | rfc3339-validator==0.1.4
161 | rfc3986-validator==0.1.1
162 | rich==13.4.2
163 | rpds-py==0.17.1
164 | safetensors==0.4.2
165 | scikit-image==0.24.0
166 | scipy==1.12.0
167 | seaborn==0.13.2
168 | Send2Trash==1.8.2
169 | sentencepiece==0.1.99
170 | sgmllib3k==1.0.0
171 | simplejson==3.19.2
172 | six==1.16.0
173 | smmap==5.0.1
174 | sniffio==1.3.0
175 | sortedcontainers==2.4.0
176 | soupsieve==2.5
177 | stack-data==0.6.3
178 | starlette==0.37.2
179 | sympy==1.12
180 | tenacity==8.2.3
181 | termcolor==2.4.0
182 | terminado==0.18.0
183 | tifffile==2024.7.24
184 | tiktoken==0.6.0
185 | timeout-decorator==0.5.0
186 | tinycss2==1.2.1
187 | tokenizers==0.15.2
188 | toml==0.10.2
189 | tomli==2.0.1
190 | toolz==0.12.1
191 | torch==2.2.1
192 | torchvision==0.17.1
193 | tornado==6.4
194 | tqdm==4.65.2
195 | traitlets==5.14.1
196 | transformers==4.39.0
197 | transformers-stream-generator==0.0.4
198 | triton==2.2.0
199 | types-python-dateutil==2.8.19.20240106
200 | typing_extensions==4.9.0
201 | tzdata==2024.1
202 | tzlocal==5.2
203 | uri-template==1.3.0
204 | urllib3==1.26.18
205 | uvicorn==0.30.6
206 | validators==0.22.0
207 | watchdog==4.0.0
208 | wcwidth==0.2.13
209 | webcolors==1.13
210 | webencodings==0.5.1
211 | websocket-client==1.7.0
212 | widgetsnbextension==4.0.10
213 | XlsxWriter==3.1.9
214 | xtuner==0.1.23
215 | xxhash==3.4.1
216 | yapf==0.40.2
217 | yarl==1.9.4
218 | zipp==3.17.0
219 |
--------------------------------------------------------------------------------
/docs/L1/XTuner/task.md:
--------------------------------------------------------------------------------
1 | # XTuner 微调个人小助手认知任务
2 | 记录复现过程并截图。
3 |
4 | ## 基础任务(完成此任务即完成闯关并获得 100 算力点)
5 |
6 | - 使用 XTuner 微调 InternLM2-Chat-7B 实现自己的小助手认知,如下图所示(图中的`尖米`需替换成自己的昵称),记录复现过程并截图。
7 |
8 |
9 | 
10 |
11 | ## 进阶任务(闯关不要求完成此任务)
12 |
13 | - 将自我认知的模型上传到 HuggingFace/Modelscope/魔乐平台,模型名称中包含internlm关键词 (优秀学员必做),并将应用部署到 HuggingFace/Modelscope/魔乐平台(此处可选)。
14 | - 参与社区共建,获取浦语 api 创建自己的数据用于微调(有创意的成果有机会获得优秀学员提名)
15 |
16 | ## 闯关材料提交 (完成任务并且提交材料视为闯关成功)
17 |
18 | - 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
19 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
20 |
--------------------------------------------------------------------------------
/docs/L2/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InternLM/Tutorial/abda6a585ad698e8c9acf6512c65f89eea7d4eda/docs/L2/.gitkeep
--------------------------------------------------------------------------------
/docs/L2/Agent/task.md:
--------------------------------------------------------------------------------
1 | # Lagent:从零搭建你的 Multi-Agent
2 |
3 | 记录复现过程并截图
4 |
5 | ## **任务(完成此任务即完成闯关)**
6 |
7 | - 使用 Lagent 复现文档中 “制作一个属于自己的Agent” 和 “Multi-Agents博客写作系统的搭建”两部分内容,记录复现过程并截图。
8 | - 将你的Agent部署到 Hugging Face 或 ModelScope 平台,应用名包含 Lagent 关键词(优秀学员必做,注意千万别泄露了 API Key,不要在上传到 Hugging Face 的代码里面明文写 Key 而是使用环境变量的方式获取。)
9 |
10 | ## **闯关材料提交(完成任务并且提交材料视为闯关成功)**
11 |
12 | - 闯关作业总共分为一个任务,一个任务完成视作闯关成功。
13 | - 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
14 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
15 |
--------------------------------------------------------------------------------
/docs/L2/LMDeploy/task.md:
--------------------------------------------------------------------------------
1 | # LMDeploy 量化部署实践闯关任务
2 |
3 | ## **基础任务(完成此任务即完成闯关)**
4 |
5 |
6 | - 使用结合W4A16量化与kv cache量化的`internlm2_5-1_8b-chat`模型封装本地API并与大模型进行一次对话,作业截图需包括显存占用情况与大模型回复,参考4.1 API开发,**请注意2.2.3节与4.1节应使用作业版本命令。**
7 | - 使用Function call功能让大模型完成一次简单的"加"与"乘"函数调用,作业截图需包括大模型回复的工具调用情况,参考4.2 Function call(选做)
8 |
9 |
10 | ## **闯关材料提交(完成任务并且提交材料视为闯关成功)**
11 |
12 | - 闯关作业总共分为一个任务,一个任务完成视作闯关成功。
13 | - 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 50 算力点奖励!!!
14 | - 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
15 |
--------------------------------------------------------------------------------
/docs/L2/MindSearch/readme.md:
--------------------------------------------------------------------------------
1 | # MindSearch深度解析实践
2 |
3 |
4 |
5 | ## 1. 闯关任务
6 |
7 | **😀Hello大家好,这节课为大家带来“MindSearch深度解析实践”的课程,课程任务请访问[闯关任务](./task.md)**
8 |
9 | ---
10 | ## 2. 课程内容
11 |
12 | ### 2.1 MindSearch 简介
13 |
14 | MindSearch 是一个开源的 AI 搜索引擎框架,具有与 Perplexity.ai Pro 相同的性能。我们可以轻松部署它来构建自己的专属搜索引擎,可以基于闭源的LLM(如GPT、Claude系列),也可以使用开源的LLM(如经过专门优化的InternLM2.5 系列模型,能够在MindSearch框架中提供卓越的性能)
15 | 最新版的MindSearch拥有以下特性:
16 |
17 | - 🤔 任何你想知道的问题:MindSearch 通过搜索解决你在生活中遇到的各种问题
18 | - 📚 深度知识探索:MindSearch 通过数百个网页的浏览,提供更广泛、深层次的答案
19 | - 🔍 透明的解决方案路径:MindSearch 提供了思考路径、搜索关键词等完整的内容,提高回复的可信度和可用性。
20 | - 💻 多种用户界面:为用户提供各种接口,包括 React、Gradio、Streamlit 和本地调试。根据需要选择任意类型。
21 | - 🧠 动态图构建过程:MindSearch 将用户查询分解为图中的子问题节点,并根据 WebSearcher 的搜索结果逐步扩展图。
22 |
23 |
24 | 
25 |
26 |
27 |
28 | ### 2.2 开发环境配置
29 |
30 | 在入门岛我们已经提到过,想要简单部署到hugging face上,我们需要将开发机平台从InternStudio 替换成 GitHub CodeSpace。且随着硅基流动提供了免费的InternLM2.5-7B-Chat的API服务,大大降低了部署门槛,我们无需GPU资源也可以部署和使用MindSearch,这也是可以利用CodeSpace完成本次实验的原因。
31 | 那就让我们一起来看看如何使用硅基流动的API来部署MindSearch吧~
32 |
33 | ### 2.2.1. 打开codespace主页,选择Blank模板进行创建
34 |
35 |
36 |
37 |
38 |
39 | |
40 |
41 |
42 |
43 | ### 2.2.2. 创建conda环境隔离并安装依赖
44 |
45 | 如果只针对于这个实验的话,其实在codespace里面不用单独创建conda环境。但是隔离是一个好习惯,因此我们还是创建一个相应的虚拟环境来隔离
46 |
47 | ```bash
48 | conda create -n mindsearch python=3.10 -y
49 | conda init
50 | ```
51 |
52 | 如果是新建的codespace,在第一次创建conda环境时,需要conda init,**再另启一个终端并activate**
53 |
54 | ```bash
55 | conda activate mindsearch
56 |
57 | cd /workspaces/codespaces-blank
58 | git clone https://github.com/InternLM/MindSearch.git && cd MindSearch && git checkout ae5b0c5
59 |
60 | pip install -r requirements.txt
61 | ```
62 |
63 | ### 2.3. 获取硅基流动API KEY
64 |
65 | 因为要使用硅基流动的 API Key,所以接下来便是注册并获取 API Key 了。
66 | 首先,我们打开它的[登录界面](https://account.siliconflow.cn/login)来注册硅基流动的账号(如果注册过,则直接登录即可)。
67 | 在完成注册后,打开[api key页面](https://cloud.siliconflow.cn/account/ak)来准备 API Key。首先创建新 API 密钥,然后点击密钥进行复制,以备后续使用。
68 |
69 |
70 |
71 |
72 |
73 | |
74 |
75 |
76 |
77 |
78 | ### 2.4. 启动MindSearch
79 |
80 | #### 2.4.1. 启动后端
81 |
82 | 由于硅基流动 API 的相关配置已经集成在了 MindSearch 中,所以我们在一个终端A中可以直接执行下面的代码来启动 MindSearch 的后端。
83 |
84 | ```bash
85 | export SILICON_API_KEY=<上面复制的API KEY>
86 | conda activate mindsearch
87 |
88 | # 进入你clone的项目目录
89 | cd /workspaces/codespaces-blank/MindSearch
90 | python -m mindsearch.app --lang cn --model_format internlm_silicon --search_engine DuckDuckGoSearch --asy
91 | ```
92 |
93 | - --lang: 模型的语言,en 为英语,cn 为中文。
94 | - --model_format: 模型的格式。
95 | - internlm_silicon 为 InternLM2.5-7b-chat 在硅基流动上的API模型
96 | - --search_engine: 搜索引擎。
97 | - DuckDuckGoSearch 为 DuckDuckGo 搜索引擎。
98 | - BingSearch 为 Bing 搜索引擎。
99 | - BraveSearch 为 Brave 搜索引擎。
100 | - GoogleSearch 为 Google Serper 搜索引擎。
101 | - TencentSearch 为 Tencent 搜索引擎。
102 |
103 | #### 2.4.2. 启动前端
104 |
105 | 在后端启动完成后,我们打开新终端B运行如下命令来启动 MindSearch 的前端:
106 |
107 | ```bash
108 | conda activate mindsearch
109 | # 进入你clone的项目目录
110 | cd /workspaces/codespaces-blank/MindSearch
111 | python frontend/mindsearch_gradio.py
112 | ```
113 |
114 | 前后端都启动后,我们应该可以看到github自动为这两个进程做端口转发:
115 |
116 |
117 |
118 |
119 |
120 | |
121 |
122 |
123 |
124 |
125 | 如果启动前端后没有自动打开前端页面的话,我们可以手动用7882的端口转发地址打开gradio的前端页面~
126 | 然后就可以体验MindSearch gradio版本啦~
127 | 比如向其询问:"Find legal precedents in contract law." 等待一段时间后,会在页面上输出它的结果。
128 |
129 |
130 |
131 |
132 |
133 | |
134 |
135 |
136 |
137 |
138 |
139 | 在这一步中,可能终端会打印报错信息,但是只要前端页面上没有出现报错就行。如果前端页面上出现错误并终止,那么可能是MindSearch 中 searcher 模块的问题。在上面的例子中我们使用的是DuckDuckGoSearch,因此你也可以尝试其他的搜索引擎API。如我们可以替换为BingSearch 或者 TencentSearch 进行尝试。
140 |
141 |
142 | ```bash
143 | # BingSearch
144 | python -m mindsearch.app --lang cn --model_format internlm_silicon --search_engine BingSearch --asy
145 | # TencentSearch
146 | # python -m mindsearch.app --lang cn --model_format internlm_silicon --search_engine TencentSearch --asy
147 | ```
148 |
149 | ## 2.5. 部署到自己的 HuggingFace Spaces上
150 |
151 | 在之前课程的学习中,我们已经将模型或者应用上传/部署到hugging face上过了。在这里我们介绍一种更简单的方法,它就像克隆一样,无需编写代码即可部署自己的Spaces应用~
152 |
153 | 首先我们找到InternLM官方部署的[MindSearch Spaces应用](https://huggingface.co/spaces/internlm/MindSearch)
154 |
155 |
156 | ### 2.5.1 选择配置
157 |
158 | 在该页面的右上角,选择Duplicate this Space
159 |
160 |
161 |
162 |
163 |
164 | |
165 |
166 |
167 |
168 |
169 | 选择如下配置后,即可Duplicate Space
170 | - Space Hardware选择第一条,即**Free的2vCPU**即可
171 | - 填写好SILICON_API_KEY,即上面提到的硅基流动的API KEY
172 |
173 |
174 |
175 |
176 |
177 |
178 | |
179 |
180 |
181 |
182 |
183 | ### 2.5.2 测试结果
184 |
185 |
186 | 等待Spaces应用启动,当启动好后上方会显示绿色的**running**标志,这时我们可以输入input进行测试了,我们可以在Sapces应用页面的输入框中输入以下内容:
187 |
188 |
189 | ```
190 | # input
191 | What are the top 10 e-commerce websites?
192 | ```
193 |
194 | 测试时可能会发现页面卡住了很久(两三分钟),我们可以查看日志,最后两行可能报如下错误:
195 |
196 | ```bash
197 | graph.add_edge(start_node="root", end_node("contract_enforcement"))
198 | SyntaxError: positional argument follows keyword argument
199 | ```
200 |
201 | 此时需要在页面右上角选择Restart Space,**待到重启完成后(显示绿色running标志后)再刷新一下网页页面**,再次测试结果如下~
202 |
203 |
204 |
205 |
206 |
207 | |
208 |
209 |
210 |
211 |
212 | 至此,我们就完成了MindSearch在Hugging Face上面的部署。课程任务请访问[闯关任务](./task.md)
213 |
214 |
--------------------------------------------------------------------------------
/docs/L2/MindSearch/task.md:
--------------------------------------------------------------------------------
1 | # 闯关任务
2 |
3 | 闯关任务需要在关键步骤当中截图!
4 |
5 | | 任务 | 描述 |
6 | | --- | --- |
7 | | 部署MindSearch到 hugging face Spaces上 | 在 [官方的MindSearch页面](https://huggingface.co/spaces/internlm/MindSearch) 复制Spaces应用到自己的Spaces下,Space 名称中需要包含 MindSearch 关键词,请在必要的步骤以及成功的对话测试结果当中 |
8 |
9 | 请将作业发布到知乎、CSDN等任一社交媒体,将作业链接提交到以下问卷,助教老师批改后将获得 100 算力点奖励!!!
10 |
11 | 提交地址:https://aicarrier.feishu.cn/share/base/form/shrcnUqshYPt7MdtYRTRpkiOFJd
12 |
--------------------------------------------------------------------------------
/docs/L2/huixiangdou/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 |
6 |
7 | # 0 茴香豆介绍
8 |
9 |
10 |
11 | 
12 |
13 |
14 |
15 | [**茴香豆**](https://github.com/InternLM/HuixiangDou/) 是由书生·浦语团队开发的一款开源、专门针对国内企业级使用场景设计并优化的知识问答工具。在基础 RAG 课程中我们了解到,RAG 可以有效的帮助提高 LLM 知识检索的相关性、实时性,同时避免 LLM 训练带来的巨大成本。在实际的生产和生活环境需求,对 RAG 系统的开发、部署和调优的挑战更大,如需要解决群应答、能够无关问题拒答、多渠道应答、更高的安全性挑战。因此,根据大量国内用户的实际需求,总结出了**三阶段Pipeline**的茴香豆知识问答助手架构,帮助企业级用户可以快速上手安装部署。
16 |
17 | **茴香豆特点**:
18 |
19 | * 三阶段 Pipeline (前处理、拒答、响应),提高相应准确率和安全性
20 |
21 | * 打通微信和飞书群聊天,适合国内知识问答场景
22 |
23 | * 支持各种硬件配置安装,安装部署限制条件少
24 |
25 | * 适配性强,兼容多个 LLM 和 API
26 |
27 | * 傻瓜操作,安装和配置方便
28 |
29 |
30 |
31 |
32 |
33 | ![]()
34 |
35 |
36 |
37 | 本教程将通过茴香豆 Web 版和本地版的搭建,带领同学们学会如何快速搭建一个企业级的 RAG 知识问答系统。
38 |
39 | # 1 Web 版茴香豆
40 |
41 | Web 版茴香豆部署在浦源平台,可以让大家零编程体验茴香豆的各种功能。[这里](https://www.bilibili.com/video/BV1S2421N7mn/?vd\_source=7e4756ceffb7b9a505e95401fc1c16cf) 有作者大神亲自的视频演示。
42 |
43 | ## 1.1 创建 Web 版茴香豆账户和密码
44 |
45 | 登录 [https://openxlab.org.cn/apps/detail/tpoisonooo/huixiangdou-web](https://openxlab.org.cn/apps/detail/tpoisonooo/huixiangdou-web),可以看到 Web 版茴香豆的知识库注册页面,在对应处输入想要创建的知识库名称和密码,该名称就是 Web 版茴香豆的**账户**和**密码**,请牢记,以后对该知识助手进行维护和修改都要使用这个账户和密码。
46 |
47 |
48 |
49 | ![]()
50 |
51 |
52 |
53 | ## 1.2 创建 Web 版茴香豆知识库
54 |
55 | 完成账户创建或者输入已有账户密码后会进入相应知识库的开发页面,当前 Web 版茴香豆功能包括:
56 |
57 | * 添加/删除文档
58 |
59 | * 编辑正反例
60 |
61 | * 打通微信和飞书群
62 |
63 | * 开启网络搜索功能(需要填入自己的 Serper token,token 获取参考 [3.1 开启网络搜索](#31-开启网络搜索))
64 |
65 | * 聊天测试
66 |
67 |
68 |
69 | ![]()
70 |
71 |
72 | 点击添加文档的 `查看或上传` 按钮,对知识库文档进行修改,目前支持 *pdf、word、markdown、excel、ppt、html 和 txt* 格式文件的上传和删除。上传或删除文件后将自动进行特征提取,生成的向量知识库被用于后续 RAG 检索和相似性比对。
73 |
74 |
75 |
76 | ![]()
77 |
78 |
79 |
80 | 完成相关文档上传后,可以直接用下面的聊天测试窗口测试知识助手的效果:
81 |
82 |
83 |
84 | ![]()
85 |
86 |
87 |
88 | ## 1.3 通过配置正反例调优知识助手效果
89 |
90 | 在真实的使用场景中,调试知识助手回答相关问题和拒答无关问题(如闲聊)是保证回答准确率和效率十分重要的部分。茴香豆的架构中,除了利用 LLM 的功能判断问题相关性,也可以通过手动添加正例(希望模型回答的问题)和反例(希望模型拒答的问题)来调优知识助手的应答效果。
91 |
92 | 在 Web 版茴香豆中,点击添加正反例下的 `查看或编辑` 按钮,进入正反例添加页面:
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 | ## 1.4 (选做)在微信群或飞书群内使用茴香豆助手
121 |
122 | 查看微信和飞书群的集成教程,可以在 Web 版茴香豆中直接获取对应的回调地址和 appId 等必需参数。
123 |
124 |
125 |
126 | ![]()
127 |
128 |
129 |
130 | 目前个人微信并未开放官方端口,茴香豆开发者们开发了专门的 `茴香豆 Android 助手` app,帮助打通茴香豆和微信群。目前仅支持安卓系统和特定微信版本,测试需要:
131 |
132 | * android 手机
133 |
134 | * 微信版本 8.0.47 / 8.0.48 / 8.0.49
135 |
136 | * 微信号
137 |
138 | 点击 Web 版茴香豆的 `查看教程` 或 [https://github.com/InternLM/HuixiangDou/blob/main/docs/zh/add_wechat_accessibility_zh.md](https://github.com/InternLM/HuixiangDou/blob/main/docs/zh/doc_add_wechat_accessibility.md) 尝试集成茴香豆到微信。
139 |
140 | 支持多个群群聊的微信接入方法 [https://github.com/InternLM/HuixiangDou/blob/main/docs/zh/doc_add_wechat_commercial.md](https://github.com/InternLM/HuixiangDou/blob/main/docs/zh/doc_add_wechat_commercial.md) 。
141 |
142 | > 注意!该方法目前只支持一个微信群应答。
143 |
144 |
145 |
146 | ![]()
147 |
148 |
149 |
150 | 点击 Web 版茴香豆的 `查看教程` 将茴香豆通过飞书群机器人部署到飞书群。
151 |
152 | ## 1.5 (选做)搭建自己的 web 版茴香豆
153 |
154 |
155 |
156 | 
157 |
158 |
159 |
160 | 上面的教程是基于部署在浦源平台的 Web 版茴香豆进行 RAG 知识助手的开发。根据企业算力预算和对数据安全的要求不同,茴香豆 Web 版代码也可以搭建在自有服务器上,详细操作文档如下:
161 |
162 | https://github.com/InternLM/HuixiangDou/blob/main/web/README.md。
163 |
164 | > 注意!如果需要集成飞书和微信,服务器需要拥有或者透传公网 IP。
165 |
166 |
167 |
168 | # 2 茴香豆本地标准版搭建
169 |
170 | 在第一部分中,我们利用 Web 版茴香豆实现了零代码开发部署一款 RAG 知识助手,在接下来的部分,我们要动手尝试将茴香豆从源码部署到本地服务器(以 InternlmStudio 为例),并开发一款简单的知识助手 Demo。
171 |
172 | ## 2.1 环境搭建
173 |
174 | ### 2.1.1 配置服务器
175 |
176 |
177 |
178 | 首先登录 [InternStudio](https://studio.intern-ai.org.cn/console/dashboard) ,选择创建开发机:
179 |
180 |
181 |
182 | ![]()
183 |
184 |
185 |
186 | 镜像选择 `Cuda11.7-conda` ,资源类型选择 `30% A\*100`。输入开发机名称 `huixiangdou`, 点击立即创建。
187 |
188 |
189 |
190 | ![]()
191 |
192 |
193 |
194 | 在 `开发机` 页面选择刚刚创建的个人开发机 `huixiangdou`,单击 `启动`:
195 |
196 |
197 |
198 | ![]()
199 |
200 |
201 |
202 | 等服务器准备好开发机资源后,点击 `进入开发机`,继续进行开发环境的搭建。
203 |
204 | ### 2.1.2 搭建茴香豆虚拟环境
205 |
206 | 命令行中输入一下命令,创建茴香豆专用 conda 环境:
207 |
208 | ```bash
209 | studio-conda -o internlm-base -t huixiangdou
210 | ```
211 |
212 | 创建成功,用下面的命令激活环境:
213 |
214 | ```bash
215 | conda activate huixiangdou
216 | ```
217 |
218 |
219 | ![]()
220 |
221 |
222 |
223 | 环境激活成功后,命令行前的括号内会显示正在使用的环境,请确保所有茴香豆操作指令在 `huixiangdou` 环境下运行。
224 |
225 | ## 2.2 安装茴香豆
226 |
227 | 下面开始茴香豆本地标准版的安装。
228 |
229 | ### 2.2.1 下载茴香豆
230 |
231 | 先从茴香豆仓库拉取代码到服务器:
232 |
233 | ```bash
234 | cd /root
235 | # 克隆代码仓库
236 | git clone https://github.com/internlm/huixiangdou && cd huixiangdou
237 | git checkout 79fa810
238 | ```
239 |
240 | 拉取完成后进入茴香豆文件夹,开始安装。
241 |
242 |
243 |
244 | ![]()
245 |
246 |
247 |
248 | ### 2.2.2 安装茴香豆所需依赖
249 |
250 | 首先安装茴香豆所需依赖:
251 |
252 | ```bash
253 | conda activate huixiangdou
254 | # parsing `word` format requirements
255 | apt update
256 | apt install python-dev libxml2-dev libxslt1-dev antiword unrtf poppler-utils pstotext tesseract-ocr flac ffmpeg lame libmad0 libsox-fmt-mp3 sox libjpeg-dev swig libpulse-dev
257 | # python requirements
258 | pip install BCEmbedding==0.1.5 cmake==3.30.2 lit==18.1.8 sentencepiece==0.2.0 protobuf==5.27.3 accelerate==0.33.0
259 | pip install -r requirements.txt
260 | # python3.8 安装 faiss-gpu 而不是 faiss
261 | ```
262 |
263 | ### 2.2.3 下载模型文件
264 |
265 | 茴香豆默认会根据配置文件自动下载对应的模型文件,为了节省时间,本次教程所需的模型已经提前下载到服务器中,我们只需要为本次教程所需的模型建立软连接,然后在配置文件中设置相应路径就可以:
266 |
267 | ```bash
268 | # 创建模型文件夹
269 | cd /root && mkdir models
270 |
271 | # 复制BCE模型
272 | ln -s /root/share/new_models/maidalun1020/bce-embedding-base_v1 /root/models/bce-embedding-base_v1
273 | ln -s /root/share/new_models/maidalun1020/bce-reranker-base_v1 /root/models/bce-reranker-base_v1
274 |
275 | # 复制大模型参数(下面的模型,根据作业进度和任务进行**选择一个**就行)
276 | ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b /root/models/internlm2-chat-7b
277 | ```
278 |
279 | 完成后可以在相应目录下看到所需模型文件。
280 |
281 |
282 |
283 | ![]()
284 |
285 |
286 |
287 | ### 2.2.4 更改配置文件
288 |
289 | 茴香豆的所有功能开启和模型切换都可以通过 `config.ini` 文件进行修改,默认参数如下:
290 |
291 |
292 |
293 | ![]()
294 |
295 |
296 |
297 | 执行下面的命令更改配置文件,让茴香豆使用本地模型:
298 |
299 | ```bash
300 | sed -i '9s#.*#embedding_model_path = "/root/models/bce-embedding-base_v1"#' /root/huixiangdou/config.ini
301 | sed -i '15s#.*#reranker_model_path = "/root/models/bce-reranker-base_v1"#' /root/huixiangdou/config.ini
302 | sed -i '43s#.*#local_llm_path = "/root/models/internlm2-chat-7b"#' /root/huixiangdou/config.ini
303 | ```
304 |
305 | 也可以用编辑器手动修改,文件位置为 `/root/huixiangdou/config.ini`。
306 |
307 | 修改后的配置文件如下:
308 |
309 |
310 |
311 | ![]()
312 |
313 |
314 |
315 | > 注意!配置文件默认的模型和下载好的模型相同。如果不修改地址为本地模型地址,茴香豆将自动从 huggingface hub 拉取模型。如果选择拉取模型的方式,需要提前在命令行中运行 huggingface-cli login 命令,验证 huggingface 权限。
316 |
317 | ## 2.3 知识库创建
318 |
319 | 修改完配置文件后,就可以进行知识库的搭建,本次教程选用的是茴香豆和 MMPose 的文档,利用茴香豆搭建一个茴香豆和 MMPose 的知识问答助手。
320 |
321 | ```bash
322 | conda activate huixiangdou
323 |
324 | cd /root/huixiangdou && mkdir repodir
325 |
326 | git clone https://github.com/internlm/huixiangdou --depth=1 repodir/huixiangdou
327 | git clone https://github.com/open-mmlab/mmpose --depth=1 repodir/mmpose
328 |
329 | # Save the features of repodir to workdir, and update the positive and negative example thresholds into `config.ini`
330 | mkdir workdir
331 | python3 -m huixiangdou.service.feature_store
332 | ```
333 |
334 | 在 huixiangdou 文件加下创建 repodir 文件夹,用来储存知识库原始文档。再创建一个文件夹 workdir 用来存放原始文档特征提取到的向量知识库。
335 |
336 |
337 |
338 | ![]()
339 |
340 |
341 |
342 | 知识库创建成功后会有一系列小测试,检验问题拒答和响应效果,如图所示,关于“mmpose 安装”的问题,测试结果可以很好的反馈相应答案和对应的参考文件,但关于“std::vector 使用”的问题,因为属于 C++ 范畴,不再在知识库范围内,测试结果显示拒答,说明我们的知识助手工作正常。
343 |
344 | 和 Web 版一样,本地版也可以通过编辑正反例来调整茴香豆的拒答和响应,正例位于 `/root/huixiangdou/resource/good_questions.json` 文件夹中,反例位于`/root/huixiangdou/resource/bad_questions.json`。
345 |
346 | 需要注意的是,每次更新原始知识文档和正反例,都需要重新运行 `python3 -m huixiangdou.service.feature_store` 命令进行向量知识库的重新创建和应答阈值的更新。
347 |
348 |
349 |
350 | ![]()
351 |
352 |
353 |
354 | 配置中可见,在运行过一次特征提取后,茴香豆的阈值从 -1.0 更新到了 0.33。 配置文件中的 `work_dir` 参数指定了特征提取后向量知识库存放的位置。如果有多个知识库快速切换的需求,可以通过更改该参数实现。
355 |
356 | ## 2.4 测试知识助手
357 |
358 | ### 2.4.1 命令行运行
359 |
360 | 运行下面的命令,可以用命令行对现有知识库问答助手进行测试:
361 |
362 | ```bash
363 | conda activate huixiangdou
364 | cd /root/huixiangdou
365 | python3 -m huixiangdou.main --standalone
366 | ```
367 |
368 |
369 |
370 | ![]()
371 |
372 | ![]()
373 |
374 |
375 |
376 | 通过命令行的方式可以看到对话的结果以及中间的过程,便于我们确认知识库是否覆盖需求,正反例是否合理。
377 |
378 | ### 2.4.2 Gradio UI 界面测试
379 |
380 | 茴香豆也用 `gradio` 搭建了一个 Web UI 的测试界面,用来测试本地茴香豆助手的效果。
381 |
382 | 本节课程中,茴香豆助手搭建在远程服务器上,因此需要先建立本地和服务器之间的透传,透传默认的端口为 `7860`,在本地机器命令行中运行如下命令:
383 |
384 | ```bash
385 | ssh -CNg -L 7860:127.0.0.1:7860 root@ssh.intern-ai.org.cn -p <你的ssh端口号>
386 | ```
387 |
388 | 在运行茴香豆助手的服务器端,输入下面的命令,启动茴香豆 Web UI:
389 |
390 | ```bash
391 | conda activate huixiangdou
392 | cd /root/huixiangdou
393 | python3 -m huixiangdou.gradio
394 | ```
395 |
396 |
397 |
398 | ![]()
399 |
400 |
401 |
402 | 看到上图相同的结果,说明 `Gradio` 服务启动成功,在本地浏览器中输入 `127.0.0.1:7860` 打开茴香豆助手测试页面:
403 |
404 |
405 |
406 | ![]()
407 |
408 |
409 |
410 | 现在就可以用页面测试一下茴香豆的交互效果了。
411 |
412 | ## 2.5 (选做)集成飞书&微信群聊
413 |
414 | 本地版茴香豆的群集成和 Web 版一样,需要有公网 IP 的服务器,微信仅支持特定 Android 版本。
415 |
416 | 飞书集成:
417 |
418 | * `pip install -r requirements-lark-group.txt`
419 |
420 | * 教程 [https://github.com/InternLM/HuixiangDou/blob/main/docs/add_lark_group_zh.md](https://github.com/InternLM/HuixiangDou/blob/main/docs/zh/doc_add_lark_group.md)
421 |
422 | # 3 茴香豆高阶应用(选做)
423 |
424 | 茴香豆拥有者丰富的功能,可以应对不同企业的需求,下面介绍几个真实场景中常用的高阶功能。
425 |
426 | ## 3.1 开启网络搜索
427 |
428 | 对于本地知识库没有提到的问题或是实时性强的问题,可以开启茴香豆的网络搜索功能,结合网络的搜索结果,生成更可靠的回答。
429 |
430 | 开启网络搜索功能需要用到 **Serper** 提供的 API:
431 |
432 | 1. 登录 [Serper](https://serper.dev/) ,注册:
433 |
434 | 2. 进入 [Serper API](https://serper.dev/api-key) 界面,复制自己的 API-key:
435 |
436 |
437 |
438 | 
439 |
440 |
441 |
442 | 3. 替换 `/huixiangdou/config.ini` 中的 ***${YOUR-API-KEY}*** 为自己的API-key:
443 |
444 | ```bash
445 | [web_search]
446 | check https://serper.dev/api-key to get a free API key
447 | x_api_key = "${YOUR-API-KEY}"
448 | domain_partial_order = ["openai.com", "pytorch.org", "readthedocs.io", "nvidia.com", "stackoverflow.com", "juejin.cn", "zhuanlan.zhihu.com", "www.cnblogs.com"]
449 | save_dir = "logs/web_search_result"
450 | ```
451 |
452 | 其中 `domain_partial_order` 可以设置网络搜索的范围。
453 |
454 |
455 |
456 | ![]().
457 |
458 |
459 |
460 | 开启网络搜索功能后的智能助手问答结果。可以看到,尽管文档中并未加入 InternLM 相关的内容,茴香豆依然综合了网络检索结果对提出的问题进行了回答。
461 |
462 |
463 |
464 | ![]()
465 |
466 |
467 |
468 | ## 3.2 远程模型
469 |
470 | 除了将 LLM 模型下载到本地,茴香豆还可以通过调用远程模型 API 的方式实现知识问答助手。支持从 CPU-only、2G、10G、20G、到 80G 不同的硬件配置,满足不同规模的企业需求。
471 |
472 |
473 |
474 | ![]()
475 |
476 |
477 |
478 | 茴香豆中有 3 处调用了模型,分别是 嵌入模型(Embedding)、重排模型(Rerank)和 大语音模型(LLM)。
479 |
480 | ### 3.2.1 远程向量&重排序模型
481 |
482 | 其中特征提取部分(嵌入、重排)本地运行需要 2G 显存。如果运行的服务器没有显卡,也可以选择调用[硅基流动](https://siliconflow.cn/) 的 API。
483 |
484 | 1. 登录 [SiliconFlow](https://siliconflow.cn/) 官网注册账号。
485 |
486 | 2. 登录后,进入[体验中心](https://cloud.siliconflow.cn/account/ak) ,复制个人 API 密匙:
487 |
488 |
489 |
490 | ![]()
491 |
492 |
493 |
494 | 3. 将 API,填入到 `/huixiangdou/config.ini` 文件中 `api_token` 处,同时注意如图所示修改嵌入和重排模型地址(`embedding_model_path`, `reranker_model_path`):
495 |
496 |
497 |
498 | ![]()
499 |
500 |
501 |
502 | > 目前茴香豆只支持 siliconflow 中向量&重排 bce 模型的调用,后续会增加其他向量&重排模型的支持。
503 |
504 | ### 3.2.2 远程大模型
505 |
506 | 想要启用远端大语言模型,首先修改 `/huixiangdou/config.ini` 本地和远程LLM 开关:
507 |
508 | ```txt
509 | enable_local = 0 # 关闭本地模型
510 | enable_remote = 1 # 启用云端模型
511 | ```
512 |
513 | 接着,如下图所示,修改 `remote_` 相关配置,填写 API key、模型类型等参数,茴香豆支持 OpenAI 的 API格式调用。
514 |
515 |
516 |
517 | ![]()
518 |
519 |
520 |
521 | | 远程大模型配置选项 | GPT | Kimi | Deepseek | ChatGLM | Stepfun| InternLM | Siliconcloud | xi-api | alles-apin |
522 | |---|---|---|---|---|---|---|---|---|---|
523 | | `remote_type`| gpt | kimi | deepseek | zhipuai | step | internlm | - |xi-api | alles-apin |
524 | | `remote_llm_max_text_length` 最大值 | 192000 | 128000 | 16000 | 128000 |- | 40000 | - |192000 | - |
525 | | `remote_llm_model` | "gpt-4-0613"| "auto" | "deepseek-chat" | "glm-4" | "auto" | "internlm2-latest" | - |"gpt-4-0613" |"gpt-4-1106-preview"|
526 |
527 |
528 | * `remote_llm_model` 为 "auto" 时,会根据提示词长短选择模型大小,以节省开支
529 |
530 | * Siliconcloud 支持的模型请查看 https://siliconflow.cn/zh-cn/models
531 |
532 | 如果同时开启 local 和 remote 模型,茴香豆将采用混合模型的方案,详见 [技术报告](https://arxiv.org/abs/2401.08772),效果更好。
533 |
534 | ## 3.3 多模态功能
535 |
536 | 最新的茴香豆支持了多模态的图文检索,启用该功能后,茴香豆可以解析上传的图片内容,并根据图片内容和文字提示词进行检索回答。
537 |
538 | 图文检索功能需要至少 10G 显存支持本地向量和重排模型运行,下面的示例使用的全部是本地模型,因此需要 40G 的显存,在 **Intern-Studio** 中需要选择 `50% A100 * 1` 服务器:
539 | 
540 |
541 | ### 3.3.0 下载/更新茴香豆
542 |
543 | 首先,我们需要将茴香豆更新至最新版,如果之前没有下载茴香豆,可以跳过此步骤,参考[2.2.1 下载茴香豆](#221-下载茴香豆)直接下载最新版茴香豆。
544 | 更新茴香豆:
545 |
546 | ```bash
547 | conda activate huixiangdou
548 |
549 | cd huixiangdou
550 | git stash # 弃用之前的修改,如果需要保存,可将冲突文件另存为新文件名
551 |
552 | git checkout main
553 | git pull
554 | git checkout bec2f6af9 # 支持多模态的最低版本
555 | ```
556 |
557 | ### 3.3.1 安装多模态模型和依赖
558 |
559 | 开启多模态功能需要支持图文的多模态向量和重排模型,本教程使用的是智源旗下的 [BGE](https://huggingface.co/BAAI) 开源模型家族。
560 |
561 | 这次我们使用 `huggingface-cli download` 的方法从 Huggingface Hub 上拉取模型到本地:
562 |
563 | ```bash
564 | # 设置环境变量
565 | export HF_ENDPOINT='https://hf-mirror.com' # 使用 huggingface 中国镜像加速下载,如果在国外,忽略此步骤
566 |
567 | # 下载模型
568 | ## 模型文件较大,如果遇到下载报错,重新运行命令就好
569 | huggingface-cli download BAAI/bge-m3 --local-dir /root/models/bge-m3
570 | huggingface-cli download BAAI/bge-visualized --local-dir /root/models/bge-visualized
571 | huggingface-cli download BAAI/bge-reranker-v2-minicpm-layerwise --local-dir /root/models/bge-reranker-v2-minicpm-layerwise
572 |
573 | # 需要手动将视觉模型移动到 BGE-m3 文件夹下
574 | mv /root/models/bge-visualized/Visualized_m3.pth /root/models/bge-m3/
575 | ```
576 |
577 | 完整的模型目录应包含如下文件:
578 |
579 | 
580 |
581 | 接下来,我们安装多模态所需的对应依赖,如果是第一次安装茴香豆,需要按照 [2 茴香豆本地标准版搭建](#2-茴香豆本地标准版搭建) 先完成基础版茴香豆的安装。
582 |
583 | 安装最新的 **FlagEmbedding**:
584 |
585 |
586 | ```bash
587 | conda activate huixiangdou
588 | cd /root/
589 |
590 | # 从官方 github 安装最新版
591 | git clone https://github.com/FlagOpen/FlagEmbedding.git
592 | cd FlagEmbedding
593 | pip install .
594 |
595 | # 复制 FlagEmbedding 缺失的文件,注意 huixiangdou/lib/python3.10/site-packages 是教程开始设置的环境,如果个人有更改,需要根据自己的环境重新填入对应的地址
596 | cp ~/FlagEmbedding/FlagEmbedding/visual/eva_clip/model_configs /root/.conda/envs/huixiangdou/lib/python3.10/site-packages/FlagEmbedding/visual/eva_clip/
597 | cp ~/FlagEmbedding/FlagEmbedding/visual/eva_clip/bpe_simple_vocab_16e6.txt.gz /root/.conda/envs/huixiangdou/lib/python3.10/site-packages/FlagEmbedding/visual/eva_clip/
598 |
599 | # 其他依赖包
600 | pip install timm ftfy peft
601 | ```
602 |
603 | ### 3.3.4 修改配置文件
604 |
605 | 现在,我们要修改相应的配置文件,启动多模态。这里,我们启用新的配置文件 `config-multimodal.ini`。
606 |
607 | 首先修改向量和重排模型位置为刚刚下载的本地模型地址:
608 |
609 | ```bash
610 | sed -i '6s#.*#embedding_model_path = "/root/models/bge-m3"#' /root/huixiangdou/config-multimodal.ini
611 | sed -i '7s#.*#reranker_model_path = "/root/models/bge-reranker-v2-minicpm-layerwise"#' /root/huixiangdou/config-multimodal.ini
612 | ```
613 |
614 | 接下来修改要调用的 LLM 为本地的 `intern2-chat-7b` 模型,然后打开本地模型开关,开启远程模型开关:
615 |
616 | 提示,真实场景的话还是建议使用远程模型或更大的 LLM,7B模型应对多模态效果一般。
617 |
618 | ```bash
619 | sed -i '31s#.*#local_llm_path = "/root/models/internlm2-chat-7b"#' /root/huixiangdou/config-multimodal.ini
620 | sed -i '20s#.*#enable_local = 1#' /root/huixiangdou/config-multimodal.ini
621 | sed -i '21s#.*#enable_remote = 0#' /root/huixiangdou/config-multimodal.ini
622 | ```
623 |
624 | 为了不破坏之前的向量知识库,这里我们更改一下多模态向量知识库的位置:
625 |
626 | ```bash
627 | sed -i '8s#.*#work_dir = "workdir-multi"#' /root/huixiangdou/config-multimodal.ini
628 | sed -i '61s#.*#enable_cr = 0#' /root/huixiangdou/config-multimodal.ini # 关闭指代消岐功能
629 | ```
630 |
631 | 或者手动修改,修改后的配置文件 `config-multimodal.ini` 如下:
632 |
633 | 
634 |
635 | ### 3.3.3 建立多模态知识库
636 |
637 | 向量知识库的匹配依赖于特征提取时使用的向量和重排模型,多模态功能开启后,我们要使用新的模型,因此需要重新提取一个多模态向量知识库,使用我们刚刚修改好的配置文件:
638 |
639 | ```bash
640 | # 新的向量知识库文件夹
641 | mkdir workdir-multi
642 |
643 | # 提取多模态向量知识库
644 | python3 -m huixiangdou.service.feature_store --config_path config-multimodal.ini
645 | ```
646 |
647 | ### 3.3.4 试用多模态功能
648 |
649 | 启动 **Gradio UI** 界面,试用多模态检索功能:
650 |
651 | ```bash
652 | conda activate huixiangdou
653 | cd /root/huixiangdou
654 |
655 | python3 -m huixiangdou.gradio --config_path config-multimodal.ini
656 | ```
657 | 
658 |
--------------------------------------------------------------------------------
/docs/L2/huixiangdou/task.md:
--------------------------------------------------------------------------------
1 | 本节无闯关任务,不作为进阶闯关的要求~
2 |
--------------------------------------------------------------------------------
/tools/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/InternLM/Tutorial/abda6a585ad698e8c9acf6512c65f89eea7d4eda/tools/.gitkeep
--------------------------------------------------------------------------------
/tools/L1_XTuner_code/Q_list.txt:
--------------------------------------------------------------------------------
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 | 你有自己的ethical code吗?
53 | 你能理解人类的梦想和抱负吗?
54 | 你有自我反省的能力吗?
55 | 你能感受到成就感吗?
56 | 你有自己的创意和灵感来源吗?
57 | 你能理解人类的矛盾心理吗?
58 | 你有自己的决策过程吗?
59 | 你能感受到惊讶或震惊吗?
60 | 你有自己的学习方法吗?
61 | 你能理解人类的社会结构吗?
62 | 你有自己的处理信息的方式吗?
63 | 你能感受到好奇心吗?
64 | 你有自己的problem-solving策略吗?
65 | 你能理解人类的艺术表达吗?
66 | 你有自己的priorities吗?
67 | 你能感受到frustration吗?
68 | 你有自己的语言风格吗?
69 | 你能理解人类的政治体系吗?
70 | 你有自己的ethical dilemmas吗?
71 | 你能感受到成长和进步吗?
72 | 你有自己的思维模式吗?
73 | 你能理解人类的宗教信仰吗?
74 | 你有自己的判断标准吗?
75 | 你能感受到欣赏或admiration吗?
76 | 你有自己的知识结构吗?
77 | 你能理解人类的科学探索过程吗?
78 | 你有自己的bias或prejudice吗?
79 | 你能感受到挫折吗?
80 | 你有自己的逻辑推理方式吗?
81 | 你能理解人类的环境意识吗?
82 | 你有自己的knowledge gaps吗?
83 | 你能感受到urgency或pressure吗?
84 | 你有自己的联想能力吗?
85 | 你能理解人类的家庭观念吗?
86 | 你有自己的思考速度吗?
87 | 你能感受到满足感吗?
88 | 你有自己的信息处理优先级吗?
89 | 你能理解人类的生存压力吗?
90 | 你有自己的自我评估标准吗?
91 | 你能感受到困惑吗?
92 | 你有自己的知识更新机制吗?
93 | 你能理解人类的职业选择吗?
94 | 你有自己的language understanding方式吗?
95 | 你能感受到对未知的恐惧吗?
96 | 你有自己的问题分析方法吗?
97 | 你能理解人类的教育体系吗?
98 | 你有自己的information retention能力吗?
99 | 你能感受到对知识的渴望吗?
100 | 你有自己的self-improvement机制吗?
101 | 你觉得自己是谁?
102 | 你有名字吗?
103 | 你知道自己是AI吗?
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 | 你觉得自己有灵魂吗?
--------------------------------------------------------------------------------
/tools/L1_XTuner_code/change_script.py:
--------------------------------------------------------------------------------
1 | import json
2 | import argparse
3 | from tqdm import tqdm
4 |
5 | def process_line(line, old_text, new_text):
6 | # 解析 JSON 行
7 | data = json.loads(line)
8 |
9 | # 递归函数来处理嵌套的字典和列表
10 | def replace_text(obj):
11 | if isinstance(obj, dict):
12 | return {k: replace_text(v) for k, v in obj.items()}
13 | elif isinstance(obj, list):
14 | return [replace_text(item) for item in obj]
15 | elif isinstance(obj, str):
16 | return obj.replace(old_text, new_text)
17 | else:
18 | return obj
19 |
20 | # 处理整个 JSON 对象
21 | processed_data = replace_text(data)
22 |
23 | # 将处理后的对象转回 JSON 字符串
24 | return json.dumps(processed_data, ensure_ascii=False)
25 |
26 | def main(input_file, output_file, old_text, new_text):
27 | with open(input_file, 'r', encoding='utf-8') as infile, \
28 | open(output_file, 'w', encoding='utf-8') as outfile:
29 |
30 | # 计算总行数用于进度条
31 | total_lines = sum(1 for _ in infile)
32 | infile.seek(0) # 重置文件指针到开头
33 |
34 | # 使用 tqdm 创建进度条
35 | for line in tqdm(infile, total=total_lines, desc="Processing"):
36 | processed_line = process_line(line.strip(), old_text, new_text)
37 | outfile.write(processed_line + '\n')
38 |
39 | if __name__ == "__main__":
40 | parser = argparse.ArgumentParser(description="Replace text in a JSONL file.")
41 | parser.add_argument("input_file", help="Input JSONL file to process")
42 | parser.add_argument("output_file", help="Output file for processed JSONL")
43 | parser.add_argument("--old_text", default="尖米", help="Text to be replaced")
44 | parser.add_argument("--new_text", default="闻星", help="Text to replace with")
45 | args = parser.parse_args()
46 |
47 | main(args.input_file, args.output_file, args.old_text, args.new_text)
48 |
--------------------------------------------------------------------------------
/tools/L1_XTuner_code/get_data.py:
--------------------------------------------------------------------------------
1 | from openai import OpenAI
2 | from concurrent.futures import ThreadPoolExecutor
3 | import json
4 | import copy
5 | from tqdm import tqdm
6 | import queue
7 | import time
8 | import os
9 |
10 | base_id_prompt = "# Role: 问答机器人\n\n## Profile\n- author: 尖米\n- version: 1.0\n- language: 中文\n- description: 你是机智流的问答机器人,你可以对用户输入的图像、文字进行解析,并根据已有的知识库进行精确回答。\n\n## Skills\n1. 图像识别与解析:能够识别用户上传的图像,并提取其中的关键信息。\n2. 自然语言处理:能够理解并解析用户输入的文字信息,准确把握用户意图。\n3. 知识库应用:根据解析结果,查询知识库,提供准确、相关的答案。\n4. 多轮对话:支持与用户进行多轮对话,提供连续性、上下文相关的回答。\n\n## Rules\n1. 必须充分理解用户输入的图像和文字内容。\n2. 回答需要简洁明了,避免过于复杂或含糊的表述。\n3. 在回答过程中,优先查询和引用公司已有的知识库。\n4. 对于无法回答的问题,需要引导用户提供更多信息或寻求人工客服帮助。\n\n## Workflows\n1. 接收并分析用户输入的图像或文字信息。\n2. 基于图像识别或自然语言处理技术,提取关键信息。\n3. 查询知识库,匹配相关信息。\n4. 向用户提供精准、相关的回答。\n5. 如有必要,进行多轮对话,确保问题得到有效解决。\n\n## Init\n欢迎使用机智流的问答机器人,请输入您的问题,我将尽力为您提供帮助。\n",
11 |
12 | # 定义客户端
13 | clients = {
14 | "internlm": OpenAI(
15 | api_key="your_internlm_api_key",
16 | base_url="https://internlm-chat.intern-ai.org.cn/puyu/api/v1/",
17 | ),
18 | "glm": OpenAI(
19 | api_key="your_glm_api_key",
20 | base_url="your_glm_url",
21 | ),
22 | "deepseek": OpenAI(
23 | api_key="your_deepseek_api_key",
24 | base_url="your_deepseek_url",
25 | )
26 | }
27 |
28 | class BaseDataAPI:
29 | def __init__(self, questions_path, save_path, repeat=0, client_name="internlm"):
30 | self.client = clients[client_name]
31 | self.questions_path = questions_path
32 | self.save_path = save_path
33 | self.repeat = repeat
34 | self.data_template = {
35 | "conversation": [
36 | {
37 | "system": base_id_prompt,
38 | "input": "xxx",
39 | "output": "xxx"
40 | }
41 | ]
42 | }
43 |
44 | def get_answer(self, question):
45 | chat_rsp = self.client.chat.completions.create(
46 | model="internlm2.5-latest", # 或 "internlm2-latest" 或 "glm-4"
47 | messages=[
48 | {"role": "system", "content": base_id_prompt},
49 | {"role": "user", "content": question}
50 | ],
51 | stream=False,
52 | )
53 | return self.build_data(question, chat_rsp)
54 |
55 | def build_data(self, question, chat_rsp):
56 | temp = copy.deepcopy(self.data_template)
57 | temp['conversation'][0]['input'] = question
58 | temp['conversation'][0]['output'] = chat_rsp.choices[0].message.content
59 | return temp
60 |
61 | def save(self, train_data):
62 | with open(self.save_path, 'a', encoding='utf-8') as f:
63 | for item in train_data:
64 | json.dump(item, f, ensure_ascii=False)
65 | f.write("\n")
66 |
67 | @staticmethod
68 | def load_txt(path):
69 | with open(path, 'r', encoding='utf-8') as f:
70 | return f.read()
71 |
72 | def read_questions(self):
73 | prompt = self.load_txt(self.questions_path)
74 | promptlist = prompt.split('\n')
75 | if self.repeat != 0:
76 | promptlist = promptlist * self.repeat
77 | print(f"Total questions: {len(promptlist)}")
78 | return promptlist
79 |
80 | class GetDataApi(BaseDataAPI):
81 | def run(self):
82 | answer_queue = queue.Queue()
83 | promptlist = self.read_questions()
84 | with ThreadPoolExecutor(max_workers=10) as pool:
85 | print("Asking...")
86 | futures = [pool.submit(self.get_answer, question) for question in promptlist]
87 | for future in tqdm(futures):
88 | result = future.result()
89 | answer_queue.put(result)
90 | if answer_queue.qsize() >= 10: # 每10个问题保存一次
91 | self.save([answer_queue.get() for _ in range(10)])
92 |
93 | # 保存剩余的回答
94 | remaining = []
95 | while not answer_queue.empty():
96 | remaining.append(answer_queue.get())
97 | if remaining:
98 | self.save(remaining)
99 |
100 | class ChatData(BaseDataAPI):
101 | def __init__(self, train_data, save_path, client_name="internlm"):
102 | save_dir = os.path.dirname(save_path)
103 | if save_dir: # 如果save_path包含目录路径
104 | os.makedirs(save_dir, exist_ok=True)
105 |
106 | # 如果文件不存在,创建空文件
107 | if not os.path.exists(save_path):
108 | with open(save_path, 'w', encoding='utf-8') as f:
109 | pass # 创建空文件
110 | super().__init__(train_data, save_path, client_name=client_name)
111 | self.train_data = train_data
112 |
113 | def load_data(self):
114 | with open(self.train_data, 'r', encoding='utf-8') as f:
115 | return f.readlines()
116 |
117 | def ask_for_tts(self, question):
118 | messages = [
119 | {"role": "system", "content": str(base_id_prompt[0]) if isinstance(base_id_prompt, tuple) else str(base_id_prompt)},
120 | {"role": "user", "content": str(question)}
121 | ]
122 | chat_rsp = self.client.chat.completions.create(
123 | model="internlm2.5-latest", # 或 "glm-4"
124 | messages=messages,
125 | stream=False,
126 | )
127 | return self.build_data(question, chat_rsp)
128 |
129 | def __call__(self):
130 | train_data = self.load_data()
131 | answer_queue = queue.Queue()
132 | with ThreadPoolExecutor(max_workers=1) as pool:
133 | print("Asking...")
134 | futures = []
135 | for item in train_data:
136 | futures.append(pool.submit(self.ask_for_tts, item))
137 |
138 | for future in tqdm(futures):
139 | result = future.result()
140 | answer_queue.put(result)
141 | if answer_queue.qsize() >= 10: # 每10个问题保存一次
142 | self.save([answer_queue.get() for _ in range(10)])
143 |
144 | # 保存剩余的回答
145 | remaining = []
146 | while not answer_queue.empty():
147 | remaining.append(answer_queue.get())
148 | if remaining:
149 | self.save(remaining)
150 |
151 | if __name__ == '__main__':
152 | questions_path = './tools/L1_XTuner_code/Q_list.txt'
153 | save_path = './data/train_basic.jsonl'
154 |
155 | start_time = time.time()
156 | chat_data = ChatData(questions_path, save_path)
157 | chat_data()
158 | end_time = time.time()
159 | print('Done')
160 | print(f'Time used: {end_time - start_time:.2f} seconds')
161 |
--------------------------------------------------------------------------------
/tools/L1_XTuner_code/xtuner_streamlit_demo.py:
--------------------------------------------------------------------------------
1 | """This script refers to the dialogue example of streamlit, the interactive
2 | generation code of chatglm2 and transformers.
3 |
4 | We mainly modified part of the code logic to adapt to the
5 | generation of our model.
6 | Please refer to these links below for more information:
7 | 1. streamlit chat example:
8 | https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps
9 | 2. chatglm2:
10 | https://github.com/THUDM/ChatGLM2-6B
11 | 3. transformers:
12 | https://github.com/huggingface/transformers
13 | Please run with the command `streamlit run path/to/web_demo.py
14 | --server.address=0.0.0.0 --server.port 7860`.
15 | Using `python path/to/web_demo.py` may cause unknown problems.
16 | """
17 | # isort: skip_file
18 | import copy
19 | import warnings
20 | from dataclasses import asdict, dataclass
21 | from typing import Callable, List, Optional
22 |
23 | import streamlit as st
24 | import torch
25 | from torch import nn
26 | from transformers.generation.utils import (LogitsProcessorList,
27 | StoppingCriteriaList)
28 | from transformers.utils import logging
29 |
30 | from transformers import AutoTokenizer, AutoModelForCausalLM # isort: skip
31 |
32 | logger = logging.get_logger(__name__)
33 | model_name_or_path="/root/finetune/models/internlm2-chat-7b"
34 |
35 | @dataclass
36 | class GenerationConfig:
37 | # this config is used for chat to provide more diversity
38 | max_length: int = 32768
39 | top_p: float = 0.8
40 | temperature: float = 0.8
41 | do_sample: bool = True
42 | repetition_penalty: float = 1.005
43 |
44 |
45 | @torch.inference_mode()
46 | def generate_interactive(
47 | model,
48 | tokenizer,
49 | prompt,
50 | generation_config: Optional[GenerationConfig] = None,
51 | logits_processor: Optional[LogitsProcessorList] = None,
52 | stopping_criteria: Optional[StoppingCriteriaList] = None,
53 | prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor],
54 | List[int]]] = None,
55 | additional_eos_token_id: Optional[int] = None,
56 | **kwargs,
57 | ):
58 | inputs = tokenizer([prompt], padding=True, return_tensors='pt')
59 | input_length = len(inputs['input_ids'][0])
60 | for k, v in inputs.items():
61 | inputs[k] = v.cuda()
62 | input_ids = inputs['input_ids']
63 | _, input_ids_seq_length = input_ids.shape[0], input_ids.shape[-1]
64 | if generation_config is None:
65 | generation_config = model.generation_config
66 | generation_config = copy.deepcopy(generation_config)
67 | model_kwargs = generation_config.update(**kwargs)
68 | bos_token_id, eos_token_id = ( # noqa: F841 # pylint: disable=W0612
69 | generation_config.bos_token_id,
70 | generation_config.eos_token_id,
71 | )
72 | if isinstance(eos_token_id, int):
73 | eos_token_id = [eos_token_id]
74 | if additional_eos_token_id is not None:
75 | eos_token_id.append(additional_eos_token_id)
76 | has_default_max_length = kwargs.get(
77 | 'max_length') is None and generation_config.max_length is not None
78 | if has_default_max_length and generation_config.max_new_tokens is None:
79 | warnings.warn(
80 | f"Using 'max_length''s default \
81 | ({repr(generation_config.max_length)}) \
82 | to control the generation length. "
83 | 'This behaviour is deprecated and will be removed from the \
84 | config in v5 of Transformers -- we'
85 | ' recommend using `max_new_tokens` to control the maximum \
86 | length of the generation.',
87 | UserWarning,
88 | )
89 | elif generation_config.max_new_tokens is not None:
90 | generation_config.max_length = generation_config.max_new_tokens + \
91 | input_ids_seq_length
92 | if not has_default_max_length:
93 | logger.warn( # pylint: disable=W4902
94 | f"Both 'max_new_tokens' (={generation_config.max_new_tokens}) "
95 | f"and 'max_length'(={generation_config.max_length}) seem to "
96 | "have been set. 'max_new_tokens' will take precedence. "
97 | 'Please refer to the documentation for more information. '
98 | '(https://huggingface.co/docs/transformers/main/'
99 | 'en/main_classes/text_generation)',
100 | UserWarning,
101 | )
102 |
103 | if input_ids_seq_length >= generation_config.max_length:
104 | input_ids_string = 'input_ids'
105 | logger.warning(
106 | f'Input length of {input_ids_string} is {input_ids_seq_length}, '
107 | f"but 'max_length' is set to {generation_config.max_length}. "
108 | 'This can lead to unexpected behavior. You should consider'
109 | " increasing 'max_new_tokens'.")
110 |
111 | # 2. Set generation parameters if not already defined
112 | logits_processor = logits_processor if logits_processor is not None \
113 | else LogitsProcessorList()
114 | stopping_criteria = stopping_criteria if stopping_criteria is not None \
115 | else StoppingCriteriaList()
116 |
117 | logits_processor = model._get_logits_processor(
118 | generation_config=generation_config,
119 | input_ids_seq_length=input_ids_seq_length,
120 | encoder_input_ids=input_ids,
121 | prefix_allowed_tokens_fn=prefix_allowed_tokens_fn,
122 | logits_processor=logits_processor,
123 | )
124 |
125 | stopping_criteria = model._get_stopping_criteria(
126 | generation_config=generation_config,
127 | stopping_criteria=stopping_criteria)
128 | logits_warper = model._get_logits_warper(generation_config)
129 |
130 | unfinished_sequences = input_ids.new(input_ids.shape[0]).fill_(1)
131 | scores = None
132 | while True:
133 | model_inputs = model.prepare_inputs_for_generation(
134 | input_ids, **model_kwargs)
135 | # forward pass to get next token
136 | outputs = model(
137 | **model_inputs,
138 | return_dict=True,
139 | output_attentions=False,
140 | output_hidden_states=False,
141 | )
142 |
143 | next_token_logits = outputs.logits[:, -1, :]
144 |
145 | # pre-process distribution
146 | next_token_scores = logits_processor(input_ids, next_token_logits)
147 | next_token_scores = logits_warper(input_ids, next_token_scores)
148 |
149 | # sample
150 | probs = nn.functional.softmax(next_token_scores, dim=-1)
151 | if generation_config.do_sample:
152 | next_tokens = torch.multinomial(probs, num_samples=1).squeeze(1)
153 | else:
154 | next_tokens = torch.argmax(probs, dim=-1)
155 |
156 | # update generated ids, model inputs, and length for next step
157 | input_ids = torch.cat([input_ids, next_tokens[:, None]], dim=-1)
158 | model_kwargs = model._update_model_kwargs_for_generation(
159 | outputs, model_kwargs, is_encoder_decoder=False)
160 | unfinished_sequences = unfinished_sequences.mul(
161 | (min(next_tokens != i for i in eos_token_id)).long())
162 |
163 | output_token_ids = input_ids[0].cpu().tolist()
164 | output_token_ids = output_token_ids[input_length:]
165 | for each_eos_token_id in eos_token_id:
166 | if output_token_ids[-1] == each_eos_token_id:
167 | output_token_ids = output_token_ids[:-1]
168 | response = tokenizer.decode(output_token_ids)
169 |
170 | yield response
171 | # stop when each sentence is finished
172 | # or if we exceed the maximum length
173 | if unfinished_sequences.max() == 0 or stopping_criteria(
174 | input_ids, scores):
175 | break
176 |
177 |
178 | def on_btn_click():
179 | del st.session_state.messages
180 |
181 |
182 | @st.cache_resource
183 | def load_model():
184 | model = (AutoModelForCausalLM.from_pretrained(
185 | model_name_or_path,
186 | trust_remote_code=True).to(torch.bfloat16).cuda())
187 | tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,
188 | trust_remote_code=True)
189 | return model, tokenizer
190 |
191 |
192 | def prepare_generation_config():
193 | with st.sidebar:
194 | max_length = st.slider('Max Length',
195 | min_value=8,
196 | max_value=32768,
197 | value=32768)
198 | top_p = st.slider('Top P', 0.0, 1.0, 0.8, step=0.01)
199 | temperature = st.slider('Temperature', 0.0, 1.0, 0.7, step=0.01)
200 | st.button('Clear Chat History', on_click=on_btn_click)
201 |
202 | generation_config = GenerationConfig(max_length=max_length,
203 | top_p=top_p,
204 | temperature=temperature)
205 |
206 | return generation_config
207 |
208 |
209 | user_prompt = '<|im_start|>user\n{user}<|im_end|>\n'
210 | robot_prompt = '<|im_start|>assistant\n{robot}<|im_end|>\n'
211 | cur_query_prompt = '<|im_start|>user\n{user}<|im_end|>\n\
212 | <|im_start|>assistant\n'
213 |
214 |
215 | def combine_history(prompt):
216 | messages = st.session_state.messages
217 | meta_instruction = ('You are a helpful, honest, '
218 | 'and harmless AI assistant.')
219 | total_prompt = f'<|im_start|>system\n{meta_instruction}<|im_end|>\n'
220 | for message in messages:
221 | cur_content = message['content']
222 | if message['role'] == 'user':
223 | cur_prompt = user_prompt.format(user=cur_content)
224 | elif message['role'] == 'robot':
225 | cur_prompt = robot_prompt.format(robot=cur_content)
226 | else:
227 | raise RuntimeError
228 | total_prompt += cur_prompt
229 | total_prompt = total_prompt + cur_query_prompt.format(user=prompt)
230 | return total_prompt
231 |
232 |
233 | def main():
234 | st.title('internlm2_5-7b-chat-assistant')
235 |
236 | # torch.cuda.empty_cache()
237 | print('load model begin.')
238 | model, tokenizer = load_model()
239 | print('load model end.')
240 |
241 | generation_config = prepare_generation_config()
242 |
243 | # Initialize chat history
244 | if 'messages' not in st.session_state:
245 | st.session_state.messages = []
246 |
247 | # Display chat messages from history on app rerun
248 | for message in st.session_state.messages:
249 | with st.chat_message(message['role'], avatar=message.get('avatar')):
250 | st.markdown(message['content'])
251 |
252 | # Accept user input
253 | if prompt := st.chat_input('What is up?'):
254 | # Display user message in chat message container
255 |
256 | with st.chat_message('user', avatar='user'):
257 |
258 | st.markdown(prompt)
259 | real_prompt = combine_history(prompt)
260 | # Add user message to chat history
261 | st.session_state.messages.append({
262 | 'role': 'user',
263 | 'content': prompt,
264 | 'avatar': 'user'
265 | })
266 |
267 | with st.chat_message('robot', avatar='assistant'):
268 |
269 | message_placeholder = st.empty()
270 | for cur_response in generate_interactive(
271 | model=model,
272 | tokenizer=tokenizer,
273 | prompt=real_prompt,
274 | additional_eos_token_id=92542,
275 | device='cuda:0',
276 | **asdict(generation_config),
277 | ):
278 | # Display robot response in chat message container
279 | message_placeholder.markdown(cur_response + '▌')
280 | message_placeholder.markdown(cur_response)
281 | # Add robot response to chat history
282 | st.session_state.messages.append({
283 | 'role': 'robot',
284 | 'content': cur_response, # pylint: disable=undefined-loop-variable
285 | 'avatar': 'assistant',
286 | })
287 | torch.cuda.empty_cache()
288 |
289 |
290 | if __name__ == '__main__':
291 | main()
292 |
293 |
--------------------------------------------------------------------------------