荒腔走板Mac电脑本地部署 LLM

最近在自己电脑上尝试着部署了下大模型,仅用此篇流水账记录一下。

环境准备

电脑 是 16寸 Mac M2 Pro,运行时内存是 16 GB。Mac 并没有独立显存,GPU 显存是和系统内存共享。

模型 选择的是 ChatGLM-6B ,它基本可以说是 10B 以下级别模型中性能最强之一。并且 ChatGLM-6B 有一个强点,就是在中英文切换对话方面表现突出。

语言 选择 Python,使用的是 3.12.2 版本,目前大多数大模型的推理过程都是用 Python 语言实现。conda 版本是 24.4.0,主要用来创建虚拟环境。下载 模型主体使用的是 modelscope,它比使用 git clone 下载模型快很多。

大模型资源准备

conda 安装

在 Terminal 中通过如下命令下载并安装 conda

go 复制代码
curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh
sh Miniconda3-latest-MacOSX-arm64.sh

安装好 conda 之后,就可以在 Terminal 里创建一个虚拟环境了。

go 复制代码
conda create -n chatglm3 python=3.12.2

创建好虚拟环境之后,通过如下命令激活创建的环境

go 复制代码
conda activate chatglm3

你会在 Terminal 中看到环境由 base 转换为 chatglm3,如下:

最后通过 conda 安装开发需要的软件,命令如下

go 复制代码
conda install pytorch torchvision torchaudio -c pytorch-nightly

这样基本的开发环境就算是配好了。顺便说下使用 conda 创建虚拟环境的最大好处就是 环境隔离。虚拟环境可以将项目的依赖隔离开来,避免与电脑系统的全局Python环境产生冲突。

下载模型 ChatGLM-6B

通常情况下是可以通过 git 命令来下载模型主体文件的

go 复制代码
git clone https://huggingface.co/THUDM/chatglm3-6b

但是上述命令在国内很有可能下载不成功,或者下载很慢。我个人建议使用 ModelScope 下载的。

使用如下命令安装 ModelScope

go 复制代码
pip install modelscope -U

然后创建一个 下载模型的 python 文件 model_download.py, 拷贝如下代码

go 复制代码
from modelscope import snapshot_download
model_dir = snapshot_download("ZhipuAI/chatglm3-6b", revision = "v1.0.0")

模型默认保存在如下路径:

go 复制代码
~/.cache/modelscope/hub/ZhipuAI/ChatGLM3-6B/

把玩大模型

环境配置好,模型也下载好。接下来就可以看下大模型能带来哪些体验了。

大模型聊天

大模型最常用也最简单的使用场景就是搭建一个chatbot。实现很简单,创建 glm_test.py 文件,代码如下:

go 复制代码
import os
import platform
from transformers import AutoTokenizer, AutoModel

MODEL_PATH = os.environ.get('MODEL_PATH', '大模型下载绝对路径')
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)

# 创建 model 实例
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True, device_map="auto", offload_folder="offload").eval()
# 调用 model.chat 方法获取大模型返回的结果
response, history = model.chat(tokenizer, "你好", history=[])

print(response)

执行上述代码,结果如下

可以看到,通过 Transformer 库直接调用 model.chat 方法就能获取大模型的返回结果。

另外,还可以将上下文保存在 history 中,再重新传给大模型。这样大模型就自带记忆功能了。 如下代码:

go 复制代码
import os
import platform
from transformers import AutoTokenizer, AutoModel

MODEL_PATH = os.environ.get('MODEL_PATH', '大模型的绝对路径')
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True).to('mps')

response, history = model.chat(tokenizer, "你好", history=[])
print(response)

response, history = model.chat(tokenizer, "我的名字叫Jiang", history=history)
response, history = model.chat(tokenizer, "我是谁 ?", history=history)
print(response)

最终执行结果如下:

简单 Prompt

除了简单的聊天功能之外,基于简单的 Prompt Engineering 可以让大模型提供更高阶点的功能。

实现信息提取

通过 Prompt,大模型可以对一定的信息进行提取,并按照要求返回特定格式。添加如下 Prompt:

go 复制代码
import os
import platform
from transformers import AutoTokenizer, AutoModel

MODEL_PATH = os.environ.get('MODEL_PATH', '大模型绝对路径')
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True).to('mps')

content="""ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,
基于 General Language Model (GLM) 架构,具有 62 亿参数。
手机号 18888888888
结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。
ChatGLM-6B 使用了较 ChatGPT 更为高级的技术,针对中文问答和对话进行了优化。
邮箱 123456789@qq.com
经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,
账号:root 密码:123456
62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答,更多信息请参考我们的博客。
"""

prompt='从上文中,提取"信息"(keyword,content),包括:"手机号"、"邮箱"、"账号"、"密码"等类型的实体,输出json格式内容'

input ='{}\n\n{}'.format(content,prompt)
print(input)

response, history = model.chat(tokenizer, input, history=[])
print(response)

最终执行结果如下:

实现 domain 理解

大模型既能做到信息提取,也能够对内容进行一定程度的理解与Mapping。就如同传统 NLU 返回的 Semantic 格式一样,基于大模型也能返回响应的格式,并且大模型的理解能力在传统 NLU 之上。添加如下 Prompt:

go 复制代码
import os
import platform
from transformers import AutoTokenizer, AutoModel

MODEL_PATH = os.environ.get('MODEL_PATH', '大模型绝对路径')
TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True).to('mps')

content="打开空调"

prompt="""
从上文中判断其所属的领域,并返回相应的domain。
所有跟空调相关的都返回domain=AC。比如我说'打开空调', 你就返回domain=AC。所有和车控操作相关的都返回domain=car_control。
比如我说打开车窗,你就返回domain=car_control。
目前你只能返回AC和car_control这2个domain,不要返回其它的domain匹配结果。

示例输入:
打开空调。
温度设置为22度。
将座椅加热调到最高。
关闭车窗。
空调风速调至最大。

示例输出:
domain=AC
domain=AC
domain=car_control
domain=car_control
domain=AC
"""

print(prompt)

input ='{}\n\n{}'.format(content,prompt)
response, history = model.chat(tokenizer, input, history=[])

print("用户输入:" + content)
print("response: ", response)

content="空调风速调高"
response, history = model.chat(tokenizer, input, history=[])
print("用户输入:" + content)
print("response: ", response)

content="打开天窗"
response, history = model.chat(tokenizer, input, history=[])
print("用户输入:" + content)
print("response: ", response)

最终执行结果如下:

可以看出,"打开空调"和"空调风速调高"这两句输入,大模型都返回了相应的 domain 。

注意:针对 "打开天窗" 大模型返回的也是 AC。很明显这是错误的,正确结果应该是 car_control。这就说明,虽然大模型理解力很强,但是还需要配合更加完善的 Prompt Engineering,甚至是 Fine Tuning。才能将大模型的潜力充分发挥。

go 复制代码
如果你喜欢本文
长按二维码关注
相关推荐
小钱c713 小时前
关于Mac使用VSCode连接虚拟机
ide·vscode·macos
Batac_蝠猫19 小时前
iOS - 自定义引用计数(MRC)
macos·ios·cocoa
SoraLuna21 小时前
「Mac畅玩鸿蒙与硬件53」UI互动应用篇30 - 打卡提醒小应用
macos·ui·harmonyos
伊织code21 小时前
报错 - decord 在 macOS Silicon 安装失败
macos·m2·decord·silicon·eva-decord
大土豆的bug记录21 小时前
Mac上鸿蒙配置HDC报错:zsh: command not found: hdc -v
macos·华为·harmonyos·arkts·鸿蒙·arkui
小远披荆斩棘21 小时前
关于Mac中的shell
macos
深度Linux21 小时前
以太网MAC和PHY层问题的“对症下药”攻略
linux·网络·macos
我是Superman丶1 天前
【工具】HTML自动识别用户正在讲话 以及停止讲话
ide·macos·xcode
Batac_蝠猫1 天前
iOS - 引用计数(ARC)
macos·ios·xcode