模型部署
通常来说,训练数据集、验证数据集、测试数据集、模型参数需要占用很多磁盘空间,数据预处理、模型的训练与推理对CPU、内存、显卡性能与数量、显存、传输带宽都有较高的要求,所以模型一般部署在远程服务器上。笔者选择将模型部署在AutoDL的云服务器上,在环境准备完成后,就可以从远程仓库拉取模型、参数以及数据集进行训练和推理了。
准备模型
这一过程一般按照模型仓库说明文档中的指示按部就班即可。
笔者部署的是llava-v1.5-7b,将其github仓库clone到本地后遵从其README文档中的指示即可部署成功,额外值得说明的一下几点。
环境变量HF_HOME和HF_ENDPOINT修改
HF_ENDPOINT
是huggingface_hub
(一个python package)下载数据时使用的镜像源(代码中会用它来从Hugging Face上拉取模型参数和配置),将其从默认的hugging face官网改成https://hf-mirror.com
可以避免科学上网,并且下载速度一般会更快。
HF_HOME
是huggingface_hub
将拉取的内容在本地保存的路径,默认为系统盘的当前用户目录下的.cache/huggingface/hub,一般拉取下来的模型参数都有数十GB,很占空间,所以建议将其改到空间更充足的数据盘。
修改环境变量的方式有两种:
- 在Python代码中
import os
并使用os.environ["<env_var_name>"] = "<env_var_value>"
修改当前执行环境的环境变量。 - 在当前命令行窗口中执行
export <env_var_name>="<env_var_value>"
,临时修改当前执行环境的环境变量,当前命令行程序退出时失效。
另一种修改hugging_hub本地模型数据存储路径的方式是,使用pip show huggingface_hub
定位该包在本地的路径(注意如果多个虚拟环境安装的话会各有一份副本,需要对每个虚拟环境修改),修改该包路径下的constants.py中default_home变量为自己指定的位置。笔者更建议通过这种方式修改,这样在一台机器上就不需要因为多个项目或者多个控制台应用而多次配置这些环境变量。
当然,将这两条export
命令写进~/.bashrc中也可以避免重复配置。
Python虚拟环境配置
创建虚拟环境时推荐查明复现模型所需的Python版本并在create时具体指定,因为一些package会依赖特定的Python版本。
使用pip安装package时推荐和作者指定的package版本完全相同,不完全一致的环境存在无法复现的风险,一般直接通过pip install -r requirements.txt
即可。
一些包,例如torch的gpu版本,可能无法据requirements.txt中指定的版本直接从pip源中拉取,因为pip源中索引不到,这时需要到torch官网或镜像站寻找对应的下载指令或者数据源url。如果本地的cuda版本和作者的不同,一般保持torch版本不变的情况下下载对应本地cuda版本的即可,例如将作者的torch==2.4.0+cu121改为和本地cuda版本对应的torch==2.4.0+cu124。
还可以使用wget将package的.whl文件下载到本地再用pip install <whl_path>
如果对应的数据源访问速度快,可以节省下载和本地build wheel的时间。
总结来说,为保证复现,需要保证当前虚拟环境的Python版本、package版本和作者指明的一致(一般在.txt或.yaml或.toml等配置文件中,较容易辨认,且可通过conda或pip等工具批量安装),在保证package版本一致的情况下,cuda版本不同一般不会影响。当然,如果cuda版本不同,比如和作者的差距过大导致互相支持的package版本不重叠,可以先安装最接近的版本尝试运行,如果出现明显不一致的行为或无法运行,再更换cuda版本。
补充
笔者建议一个研究方向的项目尽量都使用同一个虚拟环境,实在不兼容再新建虚拟环境,因为如果为每一个代码仓库都新建一个虚拟环境的话,虚拟环境太多了,难以记忆、管理维护,且相当占用存储空间。
计算资源评估
笔者使用一张24GB显存的RTX3090卡跑llava-v1.5-7b时报错显存不足了,于是花钱在云机器上加了一张同样的卡后才能跑,所以在跑模型前需先调查下作者进行模型训练与推理时的物理环境,评估下自己现有的环境能否跑得动。
准备数据集
一般来说,将从远程仓库拉取下来的数据集和参数放到模型的指定路径,并检查保证与模型代码中的路径一致,代码能找到即可。有的数据集会专门搭建一个代码框架,增加数据处理、日志记录、结果处理等功能,这时需要在框架中添加要评测的模型配置参数以及相关路径(比如模型本身代码的路径、模型参数的路径)。笔者使用的数据集是MileBench,该数据集有一个配套的评测框架。
首先从GitHub上将评测框架拉取下来,按照Python虚拟环境配置一节所述复现虚拟环境,然后根据项目的README文档中所述,根据评测模型和运行环境的具体情况,像填空一样填充或改动框架中的相关部分即可,主要有以下几点:
- 模型相关配置参数,例如模型名称、模型本身逻辑代码路径、模型参数路径(一般为.bin文件)、模型超参数配置路径(一般为.json文件,一般和模型参数.bin文件一起存放在Hugging Face仓库中)以及其他需要明确指明的参数。
- 编写被评测框架调用的模型class的具体逻辑,主要包括:
- 初始化函数
def init_components(self, config) -> None:
- 推理函数
def forward(self, questions: list[str], image_paths: list[list], device, gen_kwargs) -> list[str]:
- 初始化函数
- 与物理环境相关的参数,比如GPU个数等。
一般按照仓库文档的指示走流程即可。
如果框架使用huggingface_hub来加载和存储模型,别忘了参考环境变量HF_HOME和HF_ENDPOINT修改一节修改这两个环境变量。
即使完全遵循指示,在实际运行过程中也可能由于各种原因出现报错或者反常现象,可以通过在代码中使用print输出并在运行时将输出重定向到log文件中,然后分析log文件以及报错的trace信息估计错误位置与原因,这当然有可能是框架本身的逻辑漏洞,可以在定位溯源后根据实际情况在框架代码中添加更合理的解决代码。