dl虚拟环境搭建&GPU API镜像构建 - peter-xbs/CommonCodes GitHub Wiki

1. 基于九天平台已有虚拟环境构建定制化虚拟环境

```bash
## step1 通过vscode进入终端,conda env list查看所有虚拟环境
## step2 从已有环境pytorch1.8作为基础,复制自定义环境
conda create -n prompts --clone pytorch1.8

## step3 在prompts环境中安装基础包,使得该基础环境可在jupyterLab中显示
conda activate prompts
python -m ipykernel install --user --name prompts --display-name ""torch1.8_my""

## step4 此时重启刷新JupyterLab,可在虚拟环境列表中显示torch1.8_my,并可在该环境中安装自定义包

```

2. 自定义基础docker镜像构建

2.1 查看cuda版本

nvcc --version
# 或
cat /usr/local/cuda/version.txt

2.2 基于基础cuda镜像自定义镜像

九天深度学习平台以及相关基础设施cuda版本均为10.1,将基于cuda10.1构建系列自定义镜像

  • 相关工作总结在: https://github.com/peter-xbs/dl-api-base

  • 基础镜像:注意docker hub上镜像类型尽量选择devel类型,内部功能比较全面,而runtime/base类型为了精简经常缺失一些功能

FROM pytorch/pytorch:1.6.0-cuda10.1-cudnn7-devel
  • 基础镜像内部apg-get更新, pytorch这个镜像内部的设置,导致更新前需添加apt-key
RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub \
    && apt-get update \
    && apt-get install -y \
    curl \
    vim \
    iputils-ping \
    git \
    locales \
    logrotate \
    nginx \
    cron \
    && apt-get clean
  • 切换国内镜像源
COPY ./docker_base/.pip.conf /root/.pip/pip.conf

2.3 镜像启动注意事项

  • 物理机cuda版本需高于docker镜像cuda版本 如物理机cuda版本为10.2,而镜像cuda版本10.0-10.1均可运行

  • 如若需使用GPU,运行时添加以下参数

docker run -it --gpus=all xxx
  • 大模型文件通过挂载方式引入容器内部
docker run -it -v /model_dir/:/root/app/models xxx

model_dir内有Huggingface模型完整路径,如IDEA-CCNL/Erlangshen-SimCSE-110M-Chinese

  • 完整启动命令--entrypoint模式
docker run -it -p 8090:8000 --gpus=all -v /root/public/torch_proj/:/root/app/models --entrypoint bash text_encoder:0.0.1
  • 大模型文件从huggingface中下载
# apt-get install git-lfs
git clone https://huggingface.co/IDEA-CCNL/Erlangshen-SimCSE-110M-Chinese
  • 关于推理时model.eval()和torch.no_grad()结合使用

    • 考虑到二者目的不同:
      • with torch.no_grad - disables tracking of gradients in autograd.
      • model.eval() changes the forward() behaviour of the module it is called upon , eg, it disables dropout and has batch norm use the entire population statistics
    • 建议推理服务时可以同时使用二者,保证推理稳定的同时大大提高batch_size
  • 经实际测试,以下述代码为例

@algorithm()
def encodes_texts(texts,batch_size=64):
    all_vecs = []
    # 加载模型二郎神模型经过SimCSE优化后效果较好
    # 初始化模型
    from transformers import AutoTokenizer, AutoModelForMaskedLM

    model_p = os.path.join(model_dir, 'IDEA-CCNL/Erlangshen-SimCSE-110M-Chinese')
    token_p = os.path.join(model_dir, 'IDEA-CCNL/Erlangshen-SimCSE-110M-Chinese')
    model = AutoModelForMaskedLM.from_pretrained(model_p)
    tokenizer = AutoTokenizer.from_pretrained(token_p)
    net = torch.nn.DataParallel(model)
    model.to("cuda:0")
    def txt2emb(batch_txt):
        with torch.no_grad():
            inp = tokenizer(batch_txt, max_length=512, padding='max_length', truncation=True, return_tensors="pt")
            inp.to("cuda:0")
            out = net(**inp, output_hidden_states=True)
            res = out.hidden_states[-1][:, 0, :].cpu().numpy()

        return res.tolist()

    dataset = Dataset(texts, max_len=512)
    dataloader = torch.utils.data.DataLoader(dataset=dataset, batch_size=batch_size, shuffle=False)
    for batch in dataloader:
        vecs = txt2emb(batch)
        all_vecs.extend(vecs)
    torch.cuda.empty_cache()
    return all_vecs
  • model刚加载时,应该已经处于eval模式,因多次测试显示返回结果比较稳定一致。
  • 另外, api服务一旦启动,如使用cuda,将无法释放,一直占用,上述代码中CPU服务其实也挺快的