AI 助手降临到我身边,但是……

近期因工作需要,着手在笔记本上部署 AI 助手来帮忙翻译。

一、起因

开源翻译助手 Pot 最近遇到些问题:先是 DeepL 接口的默认 token 废弛,再是在整整一周时间内(两次滚动更新之间)都打不开。现在不少大语言模型都具备多语言能力,不过公共接口都有试用限制,我便考虑本地部署大模型,作为翻译小助手;要求既表意准确,推理也要足够快。 早前曾尝试在资料服务器上托管,但未果。

开始正题前,声明一下笔记本上的计算资源

  • 处理器:Core i5-10210U
  • 内存:16 GB,双通道 DDR4-2666,预期带宽约 40 GB/s
  • 独立 GPU:无

二、框架选项

由于缺少独立 GPU,处理器算力也有限,这里要求推理框架尽可能地轻量化。基于 Python 的各种框架:Pytorch、Transformers 等等可能太重了,不仅因为执行效率比不上 C++ 程序,也因为要连带一大堆 NVIDIA 专有框架一起安装。基于 C++ 的 llama.cpp 貌似可以接受,不仅自身开销小,也自带一个 Web app 和 OpenAI-like API 服务用来试用、托管模型。

一开始试图从 AUR 拉取,但发现依赖链庞大,拉取各种 Python 运行库很慢……转念一想,干脆拉取源码仓库来编译好了。C++ 部分仅需 cmake 即可;Python 部分虽然免于编译,但依赖链需要 pip、Pypi 仓库和特定的 Python 版本(至高 3.12.x,早于 Arch 仓库;Pytorch 尚未适配 Python 3.13+)方可建立,所以需要构建一个 Python 虚拟环境。Conda?没听说过,我用基于 C++ 的软件 micromamba,Arch CN 仓库里也正好有。

Micromamba 本身没有携带任何环境,建立虚拟环境时依赖 ~/.local/share/mamba/.mambarc 的设置;需要规定镜像源,否则拉取速度很慢。 设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
channels:
- defaults
default_channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.ustc.edu.cn/anaconda/pkgs/main
- https://mirrors.ustc.edu.cn/anaconda/pkgs/msys2
custom_channels:
bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
always_yes: true
auto_activate_base: false

这里决定构建 Python 3.12 环境。拉取 Python 包时依赖 pip 和位于 ~/.config/pip/pip.conf 的设置;pip 随环境准备完毕,设置则仅有一条简单的镜像源规则,然后拉取 Python 依赖:

1
2
[global]
index-url = https://mirrors.ustc.edu.cn/pypi/simple

如此便可利用随 llama.cpp 分发的 Python 工具(convert_hf_to_gguf.py),将 Safetensors 格式编码的模型转换为可用于 llama.cpp 的 GGUF 格式。

三、在 ModelScope 物色模型

ModelScope 是大陆环境下规模最大的开源模型平台,基本上应有尽有,跟 Hugging Face 相比毫不逊色。有两种办法拉取模型文件:

  1. 官方提供的 Python 包 modelscope。广电宽带条件下,拉取较慢但稳定于 660 kB/s 左右;不过可自由指定一个权重文件下载,灵活性高。
  2. Git 拉取整个仓库。拉取速度极快,几乎充分利用了宽带下行能力。但是,它会将一整个仓库的所有权重都下载下来,比较费硬盘。

试用过程中,我会安排以下两条元指令(System prompt/message)之一:

  1. “I want you to act as a translator. I will speak to you in English and you will translate it and answer in Chinese. Keep the meaning same, but make them more literary. I want you to only reply the correction, the improvements and nothing else, do not write explanations.” ——面向外国企业训练的模型,如 LLaMa、Gemma
  2. “你将扮演翻译员。我发给你一段英语材料,由你翻译为中文,译文需准确通顺。你只需回答译文,不给出任何解释。” ——面向大陆企业训练的原生中文模型,如“通义千问”

用这条命令启动 llama.cpp 服务:

1
./build/bin/llama-server -m qwen2.5-3b-it-Q8_0-LOT.gguf --port 8080

下面试用三款模型,均为经 INT8 量化的权重:

Gemma-X2

小米翻译特训版 Gemma-2,权重分为 20 亿(2B)和 9B。在这台本子上,2B 权重比较适合。但是,它似乎不大能理解我给予的元指令:第一条正常翻译为中文,往后回答了一串拉丁字母组成的片段(我猜测是西班牙语)。无论元指令是中文还是英文,均未改变其尴尬结局。小米没有提供如何使用、调试这个模型的资料,模型还要自行转换格式。

GLM-4

智谱于 2024 年开源的模型,权重为 9B,也是我一年来梦寐以求的。成功执行了我给予的元指令,对医学材料的理解基本到位;但推理很慢,基本在每秒 2~3 字词(tokens)之间。

Qwen2.5

“通义千问”开源版,权重从 0.5B 到 72B 不等,这里选用的是 3B。尽管权重较小,但它也成功执行了元指令,对普通英语和医学材料的理解基本到位,推理速度在每秒 8~9 tokens 之间。
推理过程需要处理器满负荷运行;虽然跟性能无关,但让风扇转速增加到 6000~7000 rpm,噪音也是挺恼人的。

llama

两段材料分别是:

医学书籍片段

Chemical classification remains useful but is rendered somewhat redundant by the broad range of chemical entities now available and by the absence of any clear structure–activity relationships for newer drugs. The chemistry of some older drugs does relate to their propensity to cause movement disorders.

化学分类仍然有用,但因其适用范围广和新药缺乏明确的结构-活性关系,而显得有些多余。一些旧药的化学性质与其引发运动障碍的倾向有关。

摘自: Taylor D M, Barnes T R E, Young A H. The Maudsley® Prescribing Guidelines in Psychiatry [M]. 14th ed. Hoboken, US: John Wiley & Sons, 2021: 3.

另一医学著作的普通英语片段

Hans Asperger used to love telling the story of his life; thus all I have to do is retell it. He was born in Vienna in 1906. His grandfather’s family had been farmers east of the capital of the Austro-Hungarian Monarchy for many generations. As a high school student, he became acquainted with the “German Youth Movement.” It was in this movement that this achievement-oriented and intellectual young man was to find all those things he valued most throughout his lifetime. There he discovered friendship, mountaineering, nature, art as a source of strength and repose, and literature—the medium in which he moved and lived.

汉斯·阿斯佩格儿曾喜欢讲述自己的故事;因此,我只需重述一遍。他1906年出生于维也纳。他的祖父家族是奥地利-匈牙利君主国东面世代从事农耕的农民。作为一名高中生,他认识到了“德国青年运动”。在这个充满目标和智力追求的年轻人身上,他一生所珍视的一切都在此找到了归宿。在那里,他发现了友谊、登山、自然、艺术作为力量和安宁的源泉,以及文学——他生活和移动的媒介。

摘自: McPartland J C, Klin A, Volkmar F R. Asperger syndrome: assessing and treating high-functioning autism spectrum disorders [M]. 2nd ed. New York, US: The Guilford Press, 2014: Foreword, x.

综上所述,Qwen2.5-3B 是适合近代(2015~2021 年)四核处理器本地部署的大语言模型;除了翻译助手,大约还可以处理其它类别的指令,不过规模和智力所限,还是莫要勉为其难罢。

四、把计算分离到资料服务器上还可行吗?

这里要考虑到两点,即不影响裸机系统(TrueNAS CE),也不使用虚拟机;早前对 TrueNAS 底层动了太多手脚,而且一旦系统更新,这些改变是不会保留的。现在想来,比较靠谱的方案可能是:启用一个 Alpine Linux 容器,其中托管 llama.cpp 并映射端口到主机指定端口上;或者干脆采用现成的 Ollama 镜像,用容器本身的设置来自主加载指定模型。

算力始终是个大问题。我曾考虑升级服务器,将处理器至少升级到 CC150(八核,算力为这部本子的两倍);再往上,功耗和噪音将指数级增加,不符合我对资料服务器的基本要求(小且安静)。GPU 推理的话,基本没多少称心如意的二手产品可捡(Tesla P4 仅仅能下探到半精度浮点,即 BF16;T10 需额外供电;INT8 等混合精度的计算自 Ampere 一代起才支持,成本激增)。利用张量单元(NPU)计算也是大有前景的方向。

上面这些想想都烦人,还是过几年再来看罢。但愿到时更多 GPU、NPU 产品沦落街头,俯拾皆是,真正实现算力普惠。