当前位置: 首页 > news >正文

【大模型部署】mac m1本地部署 ChatGLM3-6B 超详细教程

本人环境:macOS 15.5 (Sonoma) - Apple M1 / 16 G
目标:在 mac m1 16G 上 完全离线 的本地模型目录上,跑通官方 ChatGLM3-6B


目录

  1. 背景 & 踩坑记录

  2. 准备工作

  3. 新建 Conda 环境并安装依赖

  4. 关键环境变量

  5. 运行 composite_demo

  6. 常见报错与解决方案

  7. 运行效果截图

  8. 结语 & 参考链接


1 背景 & 踩坑记录

ChatGLM3-6B 出来后,很多小伙伴(包括我🙋‍♂️)直接 git clone + pip install -r requirements.txt 结果一路红 ❌:

报错

根因

ModuleNotFoundError: huggingface_hub.inference._text_generation

hub≥0.30 路径改动

ImportError: Using low_cpu_mem_usage=True ... requires Accelerate

accelerate 版本过低 / 未装

NotImplementedError: aten::isin ... on MPS

PyTorch MPS 后端缺少算子

RuntimeError: torch.classes ... __path__._path

Streamlit 热重载探测 torch.classes

因此本文一步到位给出一套「官方 issue 实测可行」的版本组合,并解释 为什么 这样配才最稳。

2 准备工作

  • 硬件:Apple M1 (16 GB 内存起步,建议 32 GB 更稳)

  • 软件

    • Conda ≥ 23.x(本文用 miniforge)

    • Git & Homebrew

  • 模型文件

~/models/chatglm3-6b/
├── config.json
├── pytorch_model-00001-of-00007.bin
├── ...
└── tokenizer.model

# 下载模型文件和权重文件 

cd models/
# 下载模型文件
git clone https://github.com/THUDM/ChatGLM3.git# 下载权重文件
# 1. 先下载小文件
GIT_LFS_SKIP_SMUDGE=1 git clone https://hf-mirror.com/THUDM/chatglm3-6b.git
# 2. 进入目录
cd chatglm3-6b
# 3. 下载大文件(分两步是方便看进度,因为权重50G,一步到位的下载看不到进度)
#git lfs pull 等价于先 git lfs fetch(只抓当前分支对应的对象)再 git lfs checkout(将指针替换为大文件)。
git lfs pull

也可以 git lfs clone https://huggingface.co/THUDM/chatglm3-6b,或从同事处拷贝离线权重。我这里是用的是代理方式下载。


3 新建 Conda 环境并安装依赖

为什么固定这些版本?

transformers 4.40.0 :ChatGLM3 官方示例锁的版本,兼容 hub<0.30
huggingface_hub 0.19.4 :仍包含旧私有路径 _text_generation
torch 2.2.2 :MPS 稳定版,兼容 peft/cpm_kernels
accelerate 0.26.0 :device_map="auto" 需要的最低版本
streamlit 1.45.1 :避免热重载新 BUG
其余库满足 GLM3 推理 + 内核 + Notebook 需求 


 新建conda 环境和下载依赖包

# 0)推荐单独新建,避免污染原有 Python
conda create -n glm3-demo python=3.10 -y && conda activate glm3-demo# 1)一次性安装“老三件”+ 其他依赖
pip install "torch==2.2.2" \"transformers==4.40.0" \"huggingface_hub==0.19.4" \"accelerate==0.26.0" \"peft==0.10.0" \"streamlit==1.45.1" \"cpm_kernels>=1.0.11" \"sentencepiece>=0.2.0" \"jupyter_client>=8.6.0"
⚠️ 注意

绝对不要 pip install -U transformers 或 pip install huggingface_hub>=0.30,否则又会踩回“私有路径丢失”坑。
如果你想体验最新功能,需手改源码 → 见第 6 节“升级方案”。 


4 关键环境变量

变量

作用

必须放在 import torch 之前

STREAMLIT_SERVER_ENABLE_FILE_WATCHER=false

关闭 Streamlit 热重载,绕开 torch.classes 路径报错

PYTORCH_ENABLE_MPS_FALLBACK=1

MPS 不支持算子时自动回退 CPU,避免 isin 报错

设置方式:(推荐)

export STREAMLIT_SERVER_ENABLE_FILE_WATCHER=false
export PYTORCH_ENABLE_MPS_FALLBACK=1

或者在 composite_demo/main.py 顶部写:(我没有这么干)

import os, torch
os.environ["STREAMLIT_SERVER_ENABLE_FILE_WATCHER"] = "false"
os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
torch.classes.__path__ = []   # 再保险

5 运行 composite_demo

cd /path/to/ChatGLM3  # 仓库根目录
streamlit run composite_demo/main.py --server.fileWatcherType none

浏览器自动打开 http://localhost:8501,就能看到下图界面👇


6 常见报错与解决方案

报错关键词

可能原因

解决办法

_text_generation Not found

hub ≥ 0.30 改路径

固定 hub==0.19.4 或改 client.py 引入

low_cpu_mem_usage=True requires Accelerate

accelerate 未装 / 版本<0.26

pip install -U accelerate>=0.26.0

aten::isin ... MPS

MPS 缺算子

export PYTORCH_ENABLE_MPS_FALLBACK=1 或安装 PyTorch Nightly

torch.classes __path__._path

Streamlit 热重载

export STREAMLIT_SERVER_ENABLE_FILE_WATCHER=false

OOM / swap 爆掉

模型全精度占内存 13 GB+

加 4-bit int 模型或 CPU+FP32

升级到最新版 transformers?

想要 4.52.x + hub 0.32.x,需要:

# client.py 旧写法
from huggingface_hub.inference._text_generation import TextGenerationStreamResult
# 改成
from huggingface_hub.inference._generated.types.text_generation import (TextGenerationStreamResult,
)

再升级库即可。


7 运行效果截图

下侧参数栏 = top_p / temperature / repetition_penalty / max_new_tokens

到此,Mac M1 完全离线跑 ChatGLM3-6B 的流程就梳理完毕。核心思想只有三点:

  1. 锁定 “老三件”(transformers 4.40 + hub 0.19 + accelerate 0.26)

  2. 关闭 Streamlit 热重载,同时 开启 MPS Fallback

  3. 缺什么补什么,不轻易乱升级

  4. 下面讲一讲这个页面的参数设置


参数设置解释:

下面用更口语化、简单易懂的话来解释这四个参数,让你一看就明白它们对生成效果的影响。

1. top_p(核采样概率)

  • 干什么的?

    控制“候选词”的范围。模型每一步会给出很多可能的词,并给出它们的“可能性”高低。top_p 就是说:我只要把概率累加到某个百分比,就把这些最有希望出现的词留下来,其他概率特别低的词就不考虑,最后在留住的那批词中随机选一个出来。

  • 怎么影响结果?

    • 如果 top_p=1.0,就意味着“全盘考虑”,所有词都有机会被选。(这跟不做 top_p 过滤等价)

    • 如果 top_p=0.8,就只在概率最前面累加到 80% 的那部分词里挑,剩下20%低概率的词被直接扔掉。这样能保证输出不会太“离谱”,也还保留了一点随机。

  • 简单说:

    • 把这个数字调小(比如 0.5),候选范围就更小,句子更“保守”、更容易生成常见表达。

    • 调到接近 1.0(比如 0.95),候选更多,生成会更“活跃”、“多样”,但也有可能出现一些冷门、奇怪的词。


2. 温度(temperature)

  • 干什么的?

    控制“随机性”的强弱。模型给每个词一个得分,接着做 Softmax 变成概率。这个概率之前会先除以温度 T:

  • 把分数 ÷ T,然后再做归一化

    • 当 T < 1 时,分数差距会被“放大”,高分词更容易被选,随机性降低,句子更“确定”。

    • 当 T > 1 时,分数差距会被“压平”,低分词的机会增大,随机性变高,句子更“花样”,可能有点“天马行空”。

  • 怎么影响结果?

    • T = 0.5(低温度):输出很稳定,几乎总是挑几率最大的词,适合希望答案很靠谱、不爱跑偏的场景。

    • T = 1.0:默认的“正常随机度”。

    • T = 1.3(高温度):输出比较活跃,可能会冒出一些有创意、没那么常见的词,但也容易跑题。

  • 简单说:

    温度越低(0.2~0.5),句子越“板正”、越不会出意外;温度越高(1.0~1.5),句子越“活泼”、“有新意”,但风险是可能会出现不太靠谱的表达。


3. 重复惩罚(repetition_penalty)

  • 干什么的?

    防止模型不停地重复同一句话或同一个词。每次模型想输出一个已经在对话里出现过的词,就给它打点折扣,让它这次不要总选同一个。

  • 怎么影响结果?

    • repetition_penalty = 1.0:不做惩罚(相当于关闭),模型可能出现“我我我……”“哈哈哈……”“再见再见……”这种重复。

    • repetition_penalty = 1.1:轻度惩罚,出现过一次的词,下次出现的可能性会被除以 1.1,能稍微抑制重复。

    • repetition_penalty = 1.3 甚至更高:惩罚力度更大,模型几乎不会重复之前那一串字。但如果惩罚过强,也可能把一些该出现的关联词也给压下去,造成句子稍微奇怪。

  • 简单说:

    想让输出更“丰富”、不要老是同样几句话循环,就把这个数字调高一点(1.1~1.2);

    想让输出更“流畅”,没什么重复烦恼,就留在 1.0~1.1。


4. 输出长度(max_new_tokens 或 max_output_length)

  • 干什么的?

    控制“最多能多说多少字”。默认是让模型在看到你的提问后,最多生成这么多个 token(token 通常相当于一个汉字或一个单词的一部分)的回答。到了上限就不再往下说了。

  • 怎么影响结果?

    • 输出长度 = 20~50:短小精悍的回答,就像一句话或两句话,适合问个小问题拿个结论。

    • 输出长度 = 256~512:回答会很长,像一段段故事、长文档、代码示例之类,适合写文章、写长段解释。

    • 如果你设置得太短,模型可能回答得过于简略;设置太长,容易让模型“唠叨”或跑题。

  • 简单说:

    这就像给模型“说话时间”的最大限制——给多少就说多少。


5. 重试 & 清除历史

  • 重试:点一次“重试”就再用当前这套参数(top_p、temperature、重复惩罚、输出长度)重新生成一个答案,通常会和上一次稍有不同,因为其中有随机采样的成分。

  • 清除历史:清掉当前对话框里已经生成过的所有问答内容,下次提问就好像从零开始,没有上下文,比较适合换话题。


简单的调参思路

  1. 想要稳定靠谱

    • 温度(temperature)调低到 0.7~0.9;

    • top_p 调到 0.8 左右;

    • 重复惩罚(repetition_penalty)设 1.0~1.1;

    • 输出长度控制在 128~256 之间。

      这样,生成的大部分句子都比较常规、不离谱,也不会乱跑题。

  2. 想要更“有趣”或“发散”

    • 温度提高到 1.1~1.3;

    • top_p 增加到 0.9~0.95;

    • 重复惩罚设 1.1~1.2;

    • 输出长度可以 256 起跳、甚至 512。

      此时会出现一些比较新奇的表达或意想不到的句子,但也要小心有时会跑偏、语义不太连贯。

  3. 只想要一句话回答

    • 输出长度设得小一些(如 20~50);

    • 温度 0.5~0.7;

    • top_p 0.8;

    • 重复惩罚 1.0~1.1。

      这样回答简短干脆,不会多说。

  4. 出现老是重复同一句话的情况

    • 把重复惩罚从 1.0 调到 1.2~1.3 看看;

    • 也可以稍微调低温度或调低 top_p,减少随机性有时也有帮助。


总结

  • top_p(核采样):控制候选词的“范围”——去掉那部分“太低概率”的词。

  • 温度(temperature):控制随机性——温度低.outputs 更确定;温度高.outputs 更随机。

  • 重复惩罚(repetition_penalty):防止循环重复——值越大越抑制重复。

  • 输出长度(max_new_tokens):规定最多能多“说”多少字,就到上限停下。

只要搞清楚它们各自的作用,就可以根据自己的需求(“要稳”还是“要酷”或“要短”)去调参,让模型输出符合预期。


8 结语 & 参考链接

  • ChatGLM3 官方 Repo

  • PyTorch GitHub Issue #77764

  • HuggingFace Hub 路径迁移 PR #2199

建议本地部署使用量化版本,因为 m1 电脑版本还是太低了,没有cuda,mps 目前还不支持,只靠cpu ,推理特别的慢,本次只是能用,建议换个好点的GPU啥的也行。

如果本文对你有帮助,不妨 点赞 / 收藏 / 关注,后续我会持续更新 深度学习,和大模型相关的知识 在 Apple Silicon 上的部署踩坑记录。

Happy Hacking! 🎉

相关文章:

  • 跟单业务和量化交易业务所涉及到的设计模式
  • 性能优化 - 理论篇:性能优化的七类技术手段
  • C++旅行预算规划 全国信息素养大赛复赛决赛 C++小学/初中组 算法创意实践挑战赛 内部集训模拟题详细解析
  • C++ - STL #什么是STL #STL的版本 #闭源开源 #STL的六大组件
  • 题解:洛谷 P12672 「LAOI-8」近期我们注意到有网站混淆视听
  • Wireshark 使用教程:让抓包不再神秘
  • DeepSeek-R1-0528,官方的端午节特别献礼
  • Go语言中的布尔类型详解
  • 【算法】贪心算法
  • 深拷贝和浅拷贝
  • C++ list数据删除、list数据访问、list反转链表、list数据排序
  • C++23 已弃用特性
  • C++ 建造者模式:简单易懂的设计模式解析
  • 【Linux 学习计划】-- 进程地址空间
  • kafka学习笔记(三、消费者Consumer使用教程——消费性能多线程提升思考)
  • 使用 HTML + JavaScript 实现一个日历任务管理系统
  • 乐观锁:高效并发无锁方案
  • SpringBoot如何实现一个自定义Starter?
  • 华为云Flexus+DeepSeek征文|华为云 Flexus X 加速 Dify 平台落地:高性能、低成本、强可靠性的云上选择
  • 第304个Vulnhub靶场演练攻略:digital world.local:FALL
  • 网站首页包含的内容怎么做/长春seo公司
  • 台州seo网站排名/湖南长沙关键词推广电话
  • 网站改版索引量下降/如何制作网站和网页
  • 那个网站做图片好看的/想学管理方面的培训班
  • 有什么做3维的案例网站/浏览器下载安装2023版本
  • 英铭广州网站建设/网络平台推广方案