本文主要介绍如何使用 Colab 从在 Hugging Face 上拉取模型,经 llama.cpp 量化,再发布到 Hugging Face。
假定已经注册了 HuggingFace,并已经生成了具备 write 权限的 API Token。

以下例子用到的模型是 zxbsmk/NSFW_13B_sft。这是一个基于百川的 Uncensored 模型,需要权限才能抓取,所以需要先注册 Hugging Face 并准备相应权限的 API Token。

  1. clone llama.cpp,然后编译出量化用的 bin

    %cd /content
    !git clone https://github.com/ggerganov/llama.cpp
    %cd llama.cpp
    !mkdir build
    %cd build
    !apt install cmake
    !cmake ..
    !cmake --build . --config Release
  2. 通过脚本拉取模型,官方的有点慢,这里使用第三方的脚本

    %cd /content
    !apt -y install -qq aria2
    !wget https://gist.github.com/padeoe/697678ab8e528b85a2a7bddafea1fa4f/raw/5542d6c7ea6544b296dfcec770a74c74c5c01325/hfd.sh
    !bash /content/hfd.sh zxbsmk/NSFW_13B_sft --tool aria2c -x 4 --hf_username ?USERNAME? --hf_token ?hf_API-TOKEN?
  3. 准备修改过的转换脚本,有两处改动。第一是 KerfuffleV2 提供的 --pad_vocab 参数,用于修正 vocab mismatch 错误;第二是修正部分模型需要从 config.json 中读取 model_max_length 作为 n_ctx

    !pip install sentencepiece
    %cd /content
    # download a patched converter.py
    !wget https://pastebin.com/raw/bedgE0Px -O ./llama.cpp/convert.py
    !python ./llama.cpp/convert.py --padvocab --outtype f16 ./NSFW_13B_sft/ #default name:ggml-model-f16.gguf
  4. 开始量化。Colab 大约能提供 108G 的硬盘,量化完一个模型大约需要 90G 或更多,所以只能分批量化。根据 TheBloke 推荐,Q4_K_M、Q5_K_S、Q5_K_M 性价比较高。

    %cd /content
    %cd NSFW_13B_sft
    !../llama.cpp/build/bin/quantize ./ggml-model-f16.gguf ./nsfw-13b-sft.Q4_K_M.gguf Q4_K_M
    # !../llama.cpp/build/bin/quantize ./ggml-model-f16.gguf ./nsfw-13b-sft.Q5_K_S.gguf Q5_K_S
    # !../llama.cpp/build/bin/quantize ./ggml-model-f16.gguf ./nsfw-13b-sft.Q5_K_M.gguf Q5_K_M
  5. 去 Hugging Face 上新建模型,假设名称为NSFW_13B_sft-GGUF。清理目录,clone 所有非模型文件。

    %cd /content
    %rm -rf ./NSFW_13B_sft-GGUF
    !GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/?USERNAME?/NSFW_13B_sft-GGUF
    %cd NSFW_13B_sft-GGUF
    !huggingface-cli lfs-enable-largefiles .
  6. 将量化后的模型移到目录中。

    %cd /content
    !mv ./NSFW_13B_sft/nsfw-13b-sft.Q4_K_M.gguf ./NSFW_13B_sft-GGUF/
    !ls ./NSFW_13B_sft-GGUF
  7. 正式发布模型。git push 可能会提示找不到用户名,借用 expect 可以顺利上传,密码是 API Token(注意要有 write 权限),可能需要输入两遍用户名密码。

    %cd /content
    %cd ./NSFW_13B_sft-GGUF
    !git lfs track "*.gguf"
    !git config --global user.email "?EMAIL?"
    !git config --global user.name "?USERNAME?"
    !git add .
    !git commit -m "GGUF model commit (made with llama.cpp)"
    # !git push
    !apt install expect
    context = """
    spawn git push
    interact
    """
    with open("/content/push.txt", "w") as f:
        f.write(context)
    !expect /content/push.txt
  8. 重复步骤:5 清空目录 → 4 量化另一个精度 → 6 & 7 再重新移动文件、上传。

*注1:如需使用 API 登录,可使用单行命令
!python -c "from huggingface_hub.hf_api import HfFolder; HfFolder.save_token('?hf_API-TOKEN?')"

注2:Kaggle push 大文件有问题,可以使用官方 API 上传,但文件必须 <5G。详情见官方文档。

注3:国内有很多非标的 llama 模型,如 01-ai/Yi、vivo-ai/BlueLM,无法直接转换,或需要用到各种奇怪的技巧甚至修改推理代码,还有一些模型如 chatglm3,转换后无法加载,原因未知。