大模型应用:大模型实测对比:1.8B vs 6B,本地部署的极限拉扯与真实体感.119
一、前言
在本地部署大模型的圈子里,一直存在着一场关于显存与参数量的博弈,受限于本地PC的硬件限制,我们通常都用的是1.5B的小体量模型,现在随着硬件条件的加持,我们也尝试应用更大的模型,看看当“大而全”遇上“小而美”有什么样的变化和差异;
新选的ChatGLM2-6B,60 亿参数让它拥有不错的逻辑推理能力和中文理解力,是许多开发者心中的标准答案。但它的门槛也显而易见:我们需要一张至少 8GB 显存的显卡还得量化,或者忍受 CPU 推理的龟速。另一边是我们常用的 Qwen1.5-1.8B,通义千问家族的轻量级选手。不到 20 亿的参数,让它能在任何一台稍微现代的笔记本甚至树莓派上流畅运行。很多人对它持怀疑态度:“这么小的模型,真的能干活吗?还是只能陪聊?”
今天我们分别部署了通义千问的 Qwen1.5-1.8B-Chat和智谱的 ChatGLM2-6B,这两个模型分别代表了轻量高效和性能均衡两个方向。我们直接上手代码,通过两段真实的 FastAPI 部署脚本,将这两个模型拉上擂台,从部署难度、推理效果、硬件要求、实际应用,来一场全方位的贴身肉搏。看看在大模型盛行的当下,为了那点极致的轻量化,我们到底牺牲了多少智能?又换回了怎样的自由?

二、基础认知
在我们实测之前,先明确核心概念:这里的1.5B、6B指的是模型的参数量,分别约 15 亿、60 亿,参数量直接决定了模型的知识容量和推理能力,简单说,参数量越大,模型能记住的知识越多、理解复杂问题的能力越强,但同时对硬件的要求也越高。
| 核心维度 | Qwen1.5-1.8B-Chat | ChatGLM2-6B |
|---|---|---|
| 参数量 | 18 亿(标称 1.5B) | 60 亿 |
| 研发团队 | 通义千问 | 智谱 AI |
| 训练数据 | 通用中文 + 英文语料 | 中文优化语料 |
| 部署门槛 | 极低(CPU 即可跑) | 中等(建议 GPU) |
| 推理速度 | 极快(CPU≈10 字 / 秒) | 中等(CPU≈2 字 / 秒,GPU≈20 字 / 秒) |

三、部署体验对比
1. 代码层面的差异
1.1 ChatGLM2-6B (60 亿参数)
看第一段代码,我们会发现加载 ChatGLM2 的过程需要适配兼容性,进行加载容错。
# 修复ChatGLM配置兼容性问题
config = AutoConfig.from_pretrained(local_model_path, trust_remote_code=True)
if not hasattr(config, 'max_length'):
config.max_length = config.seq_length ...
# 尝试加载,失败则换一种姿势
try:
model = AutoModel.from_pretrained(..., torch_dtype=torch.float16)
except Exception as e:
# 兜底方案:直接导入特定类
from transformers import ChatGLMForConditionalGeneration
model = ChatGLMForConditionalGeneration.from_pretrained(...)
难点分析:
- 1. 版本依赖敏感:AutoModel 可能加载失败,需要兜底用专用类,正如代码中那个 try-except 块所示,ChatGLM2 对 transformers 库的版本非常挑剔。新版本往往修改了内部属性(如 all_tied_weights_keys),导致旧模型加载报错。我们必须要经历调试容错以平衡库的版本。
- 2. 特殊配置修补:需要手动修补 max_length 属性,这是因为早期 ChatGLM 的配置定义与新版的 HuggingFace 标准不完全兼容。
- 3. 内存压力:即使使用了 torch.float16,6B 模型在半精度下也需要约 12GB+ 的显存。如果显存不足,必须开启 low_cpu_mem_usage 或进行 4-bit/8-bit 量化,这又引入了额外的复杂性。
- 4. 模型体积大:下载包约 14GB,需要更大的缓存空间,下载时间更长
1.2 Qwen1.5-1.8B (18 亿参数)
再看 Qwen 的代码,简直是清流,极简主义,几乎零适配
# 关键:模型会自动下载并加载
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(local_model_path, trust_remote_code=True)
优点分析:
- 1. 无需修复配置:代码里没有任何补全 max_length、适配模型类的容错逻辑,直接加载就能用
- 2. 标准化接口:完全遵循 HuggingFace 的标准 AutoModelForCausalLM 接口,没有奇怪的属性缺失,不需要手动修补配置。
- 3. 极简主义:没有复杂的 try-except 兜底,没有特殊的类导入。代码行数直接减半。
- 4. 资源友好:1.8B 模型在半精度下仅需约 3.5GB 显存,甚至可以在纯 CPU 模式下以可接受的速度运行,虽然慢点,但不会崩。这意味着我们不需要昂贵的高配显卡,一张普通的RTX 3060甚至集成显卡都能跑。
- 5. 模型体积小:下载包仅 4GB 左右,普通机械硬盘几分钟就能下完
1.3 最直观的感觉
- 加载 ChatGLM2 像是在组装一台精密仪器,我们需要查阅说明书,担心零件不兼容;
- 加载 Qwen1.5 像是冲泡一杯速溶咖啡,撕开包装,加水,搞定。
2. 硬件部署门槛
我们用同一台中等配置的服务器做了测试,硬件配置:Intel i7-12700H(16 核)+ 32GB 内存 + RTX 3060(6GB 显存),测试结果如下:
| 部署方式 | Qwen1.5-1.8B | ChatGLM2-6B |
|---|---|---|
| CPU 部署 | 流畅运行,加载耗时≈30 秒 | 能运行但加载慢(≈5 分钟),推理卡顿 |
| GPU 部署 | 加载≈10 秒,推理无感知 | 加载≈1 分钟,推理流畅 |
| 显存占用 | GPU≈1.2GB | GPU≈4.5GB |
| 内存占用 | CPU≈4GB | CPU≈12GB |
总的来说,Qwen1.5-1.8B 是真轻量,哪怕是老旧的办公电脑只有8GB内存也能跑;ChatGLM2-6B 虽然比 13B、70B 模型轻量,但CPU部署体验很差,必须要有独立显卡才能用得流畅。

三、推理效果对比
光看部署体验不够,模型最终还是要能干活,我们通过5类典型的应用场景,分别测试两个模型的表现,看看6B的智商是不是真的碾压1.5B;
1. 模型运行启动
Qwen1.5-1.8B运行启动示例:

ChatGLM2-6B运行启动示例:

2. 基础问答(事实性问题)
测试问题:“2008年奥运会举办地”
2.1 Qwen1.5-1.8B 输出结果:
{
"question": "2008年奥运会举办地",
"answer": "2008年奥运会举办地北京位于我国四大地理区域中的( )\nA. 南方地区\nB. 北方地区\nC. 西北地区\nD. 吉藏地区\n\n答案:B\n解:北京市位于太行山、燕山和华北平原的结合部,是我国的首都,是全国的政治、文化、交通、科研、教育中心,也是世界上著名的历史文化名城和国际化大都市。\n解析:我国幅员辽阔,自然环境复杂多样,形成了各具特色的地理区域,在中国地图上,把秦岭-淮河线、400毫米年等降水量线和青藏高原边缘线这三条重要的地理界线结合起来,并根据实际情况作一定的调整,就把我国划分为四大地理区域,即北方地区、南方地区、西北地区和青藏地区."
}

核心问题:过度联想与任务错位,幻觉明显
- 现象:用户只是询问一个简单的事实,模型却强行将其识别为一道初中地理选择题。它不仅编造了选项A/B/C/D,还给出了标准答案格式。
- 原因推测:1.8B 的小参数模型在训练数据中可能见过大量类似的地理考题,导致其模式匹配能力过强但理解能力不足。它没有理解用户是在提问,而是误判为用户在“求解题”或“测试地理知识”,从而触发了错误的回复模板。
- 评价:虽然最终信息点在事实层面没错,但答非所问,交互体验极差,显得不够智能,像是在背诵教科书而不是对话。
2.2 ChatGLM2-6B 输出结果:
{
"question": "2008年奥运会举办地",
"answer": "2008年奥运会举办地是北京。"
}

核心表现:意图理解准确,回答简洁
- 现象:模型直接捕捉到了用户的核心需求,给出了最直白的答案:“2008年奥运会的举办地是北京。”
- 原因推测:6B 参数量带来了更强的语义理解能力和指令遵循能力。它能区分“闲聊/问答”与“解题”的场景差异,没有被训练数据中的考题模式带偏。
- 评价:回答精准、克制,符合人类对话的自然逻辑,没有多余的废话或错误的格式。
总结:Qwen1.5-1.8B 暴露了小参数模型常见的“过度拟合训练数据格式”的弱点,它记住了地点和地理题经常一起出现,就错误地认为只要提到地点就要输出地理题解析。而 ChatGLM2-6B 则展示了参数量带来的通用理解能力,知道什么时候该简单回答,什么时候该详细解释。
3. 中文理解(语境/歧义处理)
测试问题:“他背着我去了银行,我很生气 —— 请分析这句话的两个歧义”
3.1 Qwen1.5-1.8B 输出结果:
{
"question": "他背着我去了银行,我很生气 —— 请分析这句话的两个歧义",
"answer": "他背着我去了银行,我很生气 —— 请分析这句话的两个歧义。\n\n第一个歧义是指说话者在说"我很生气"时,实际上指的是说话者的愤怒情绪。在这种情况下,句子可以理解为:\n\n"我非常生气,因为我背着你去银行。“\n\n在这个表达中,“我"是主语,表示说话者自己的感受和状态;"很生气"是谓语动词,表示说话者的情绪状态;“因为”引导了一个原因状语从句,说明了为什么说话者感到生气;"背着他"是一个方式状语成分,表示说话者采取的行为,即独自一人带着某人前往银行。\n\n第二个歧义是指说话者在说"我很生气"时,实际上指的是说话者对说话者自己所做的事情感到不满或不赞同。在这种情况下,句子可以理解为:\n\n"我不高兴,因为我背着你去银行。“\n\n在这个表达中,"我"依然是主语,表示说话者自己的感受和状态;“很生气"仍然是谓语动词,表示说话者的情绪状态;“因为"引导了一个原因状语从句,说明了为什么说话者感到生气;“背着他"仍然是一个方式状语成分,表示说语者采取的行为,即独自一人带着某人前往银行。\n\n因此,这两个歧义都表达了说话者对自己独自一个人去银行的行为感到不满或不赞同,只是前者更强调了这个行为的原因(即“背着你",而不是直接提到他的愤怒情绪),而后者则更侧重于这个行为本身(即“背着你",而不是直接提到他对自己的不满或不赞同)。两种解释都可以合理地描述说话者的反应,但它们可能需要根据上下文的具体情境进行选择和调整。例如,在一个朋友之间的情境下,可能会更加倾向于将第二个解释应用,因为在这种情况下,朋友之间通常会相互尊重、支持和关心对方,而不是指责或批评自己的行为。而在一个严肃的商业环境中,可能会更加倾向于将第一个解释应用,因为在这种情况下,银行交易涉及到个人财务安全和信用记录,而单独一人携带客户前往银行可能会引发不必要的风险和疑虑。"
}

- 乍一看内容很丰富,第一感觉是很分析的很具体,但仔细一看,确是胡言乱语,文不对题,这就是典型的大模型幻觉问题;
- 只看出“背着”的字面意思,特指身体动作,没理解”隐瞒“的引申义,只分析出1个歧义
3.2 ChatGLM2-6B 输出结果:
{
"question": "他背着我去了银行,我很生气 —— 请分析这句话的两个歧义",
"answer": "这句话有两个可能的歧义:\n\n1. 他背着我去银行,我感到生气。\n\n这个歧义表达了说话者对他的行为感到不满,即他背着我去银行,这是一个不恰当的行为,我感到生气。\n\n2. 我生气,因为我发现他背着我去银行。\n\n这个歧义表达了说话者的情感反应,即他们感到生气,因为他们发现对方做了一个让他们不满意的事情,即背着他们去银行。"
}

言简意赅的指出两个歧义:
- 1. 背着 = 身体动作,指用背驮着;
- 2. 背着 = 隐瞒,指违背对方意愿做的事情;
总结:6B 模型对中文语境、多义词的理解能力是 1.5B 的降维打击,这和 ChatGLM2 专门优化中文语料直接相关。
4. 逻辑推理(简单数学推理)
测试问题:“3个人3天用3桶水,9个人9天用几桶水”
4.1 Qwen1.5-1.8B 输出结果:
{
"question": "3个人3天用3桶水,9个人9天用几桶水",
"answer": "3个人3天用3桶水,9个人9天用几桶水?\n解:(1)9÷($\\frac{1}{3}$×3)\n=9÷1\n=9(桶)\n答:9个人9天用9桶水.\n解析:3个人3天用3桶水,那么每个人每天用水的桶数是$\\frac{1}{3}$桶;9个人9天用的桶数就是9个$\\frac{1}{3}$桶,即9÷$\\frac{1}{3}$桶."
}
解析过程整理:3个人3天用3桶水,那么每个人每天用水的桶数是1/3桶;9个人9天用的桶数就是9个1/3桶,即9÷(1/3)桶.

最终结论:错误(答案是 9 桶水)。
过程分析:逻辑混乱,幻觉明显,思路到最后是正常的,但答案和思路完全不在一个频道上。
- 分析过程中说的“每个人每天用水的桶数是1/3桶”,这是正确的。
- Qwen的逻辑是:3人3天3桶 → 1人3天1桶 → 1人1天 1/3 桶。
- 让我们重新算一遍:
- 3人 3天 = 3桶
- 3人 1天 = 1桶 (3桶 ÷ 3天)。
- 1人 1天 = 1/3 桶 (1桶 ÷ 3)
- 9人 1天 = 3桶 (1/3桶 × 9)。
- 9人 9天 = 27桶 (3 × 9)。
- 计算逻辑混乱:它写的算式是 9 ÷ (1/3 × 3) 或者文字描述 9个1/3桶,即 9 ÷ 1/3。
- 如果是“9个1/3”,应该是乘法 9×1/3=3。
- 如果是 9÷1/3 ,结果是 27。
- 它的算式 9 ÷ 1 = 9 完全是凑出来的。
- 评价:回答了9,这像我们常犯的直觉错误,数学上的线性叠加错误,它可能也是“背”了这个错误答案,或者逻辑和答案没有支撑。
4.2 ChatGLM2-6B 输出结果:
{
"question": "3个人3天用3桶水,9个人9天用几桶水",
"answer": "根据“3个人3天用3桶水”,可以得出每个人每天平均消耗1桶水。\n\n因此,9个人9天需要的总水量为:9个人 × 9天 × 1桶/人/天 = 81桶水。"
}

最终结论:严重错误(答案是 81 桶水)。
过程分析:
- 第一步就错了:它声称“根据‘3个人3天用3桶水’,可以得出每个人每天平均消耗1桶水”。
- 事实:3人3天3桶 → 1人1天应该是 1/3 桶。
- 错误点:它忽略了“3天”和“3人”的双重稀释效应,简单地认为 3/3/3 = 1,或者是某种奇怪的线性直觉,直接得出了错误的单位效率。
- 连锁反应:基于错误的单位效率(1桶/人/天),它进行了正确的乘法运算:9×9×1=81 。
- 评价:这是典型的“逻辑链断裂”。6B 模型试图通过推理来解决问题,而不是背诵答案。然而,它在最基础的归一化步骤(求出单人单日效率)上犯了低级错误,导致后续计算虽然逻辑自洽,但结果南辕北辙。这显示了即使是 6B 模型,在处理需要多步思维转换的数学陷阱题时,依然容易想当然。
总结:Qwen1.5-1.8B 犯了直觉错误;ChatGLM2-6B 犯了计算前提错误,这也说明了不要完全信任大模型做复杂的数学逻辑题,尤其是这种带有陷阱的奥数题,它们很容易在“归一”步骤或“倍数”关系上出错。
5. 文本生成(作文/文案)
测试要求:“写一段100字左右的春日公园文案”
5.1 Qwen1.5-1.8B 输出结果:
{
"question": "写一段100字左右的春日公园文案",
"answer": "写一段100字左右的春日公园文案。\n\n春风拂面,绿意盎然。春天的公园犹如一幅生动的画卷,色彩斑斓、生机勃勃。公园内的花儿竞相开放,红的似火,粉的如霞,黄的如金,构成了一幅五彩斑斓的春天画卷。微风轻轻吹过,花瓣飘落,仿佛在为大地铺上一层薄薄的地毯,让人心旷神怡。孩子们在草地上奔跑嬉戏,笑声回荡在空气中,为这个宁静的公园增添了一份活力与欢乐。人们纷纷来到这里,享受着春天的气息,感受大自然的魅力,这是一片充满生机和希望的地方,让人流连忘返。"
}

优点:文采斐然,画面感强
- 用词丰富(“红的似火,粉的如霞,黄的如金”),修辞手法运用得当,读起来很有文学色彩,像是一篇成熟的散文片段。
- 情感渲染到位,从视觉(花色)到触觉(微风)再到听觉(笑声),感官描写全面。
缺点:指令遵循度低(重复问题 + 字数超标)
- 重复输入:回答的开头直接复述了用户的问题“写一段100字左右的春日公园文案。”,这是小模型常见的复读机现象,显得不够智能,像是在做填空题而不是对话。
- 字数失控:用户要求“100字左右”,实际统计其正文部分(不含重复的问题)约为 160字 左右。对于“100字左右”这种约束,它明显超纲了,缺乏对长度的精准控制。
5.2 ChatGLM2-6B 输出结果:
{
"question": "写一段100字左右的春日公园文案",
"answer": "春日公园,绿意盎然。阳光洒下,微风拂面,空气清新,鸟儿欢唱。这里是您和家人放松心情,共享自然美景的好去处。在这里,您可以看到树木葱郁,湖泊清澈,花坛绚丽,春意盎然。您可以和家人一起散步,聊天,野餐,或者仅仅静静地欣赏美景。在这里,您可以感受到大自然的魅力,享受一份宁静与美好。快来春日公园,与我们一起享受这美好的时光吧!"
}

优点:指令遵循度高,结构清晰
- 干净利落:没有复述问题,直接进入主题,符合对话助手的身份。
- 字数控制较好:正文部分约为 130字 左右。虽然也略微超过了100字,但相比Qwen的160字,它更接近用户的预期范围。
- 互动性强:文案中使用了“您”、“快来...与我们一起”等呼唤性语句,更像是一段真正的“公园宣传文案”或“邀请函”,场景代入感更强。
缺点:文采略显平淡
- 用词相对常规(“绿意盎然”、“空气清新”、“树木葱郁”),缺乏Qwen那种细腻的比喻和色彩描绘,读起来稍显套路化,像是一个标准的模板生成的。
总结:在创意写作任务中,参数量带来的指令理解能力(ChatGLM2)比单纯的文采堆砌(Qwen1.5)更具实用价值。毕竟,写得再好如果还要人工删减开头和控制字数,效率就低了。
6. 代码能力(简单Python脚本)
测试要求:“写一段Python代码,实现计算1到100的和”
6.1 Qwen1.5-1.8B 输出结果:
{
"question": "写一段Python代码,实现计算1到100的和",
"answer": "写一段Python代码,实现计算1到100的和\n\n```python\nsum = 0\nfor i in range(1, 101):\n sum += i\nprint(\"1到100的和为:\", sum)\n```\n\n这段代码首先初始化一个变量`sum`为0,然后使用一个`for`循环从1遍历到100。在每次迭代中,它将当前数`i`加到`sum`上。最后,代码打印出1到100的和。\n\n运行这段代码,你会得到以下输出:\n\n```\n1到100的和为: 5050\n```"
}

- 闭环验证:不仅给出了代码,还主动提供了运行输出示例(1到100的和为:5050)。这对于用户来说非常友好,相当于直接告诉用户跑起来是这个样子,增加了可信度。
- 解释清晰:对代码逻辑的解释分步明确(初始化->循环->累加->打印)。
- 复读机习惯:再次出现了复述用户问题的情况(“写一段Python代码...”),这是小模型常见的冗余。
6.2 ChatGLM2-6B 输出结果:
{
"question": "写一段Python代码,实现计算1到100的和",
"answer": "以下是一段Python代码,可以计算1到100之间的和:\n\n```\nsum = 0\nfor i in range(1, 101):\n sum += i\nprint(\"1到100的和为:\", sum)\n```\n\n代码中使用了Python内置的`range`函数来生成1到100的整数序列,然后使用`for`循环来迭代这些数字,将它们相加并累加到一个变量`sum`中。最后,使用`print`函数来输出计算出的总和。"
}

- 无冗余:没有复述问题,直接给出“以下是...”,进入主题快。
- 解释到位:明确提到了 range 函数的作用和迭代逻辑,解释更加贴合 Python 的术语风格。
- 缺少反馈:没有展示代码运行后的结果。对于新手用户,可能不知道代码跑出来对不对,少了Qwen 那种所见即所得的安心感。
四、细节差异对比
1. 交互习惯(指令遵循)
- Qwen1.5-1.8B:有严重的复读机倾向,习惯在回答开头原样复述用户问题,显得冗余且不够智能。
- ChatGLM2-6B:指令遵循更好,直接切入主题,无多余复述,对话感更自然。
2. 逻辑与推理能力
- Qwen1.5-1.8B:依赖记忆而非推理。
- 遇到网红题(如奥数题)能靠背诵给出正确答案,但解释过程胡编乱造,出现幻觉。
- 遇到非标准问题(如简单问答)容易过度联想,强行套用训练数据中的特定格式,误把问答变成考试题。
- ChatGLM2-6B:尝试推理但易犯错。
- 试图通过逻辑推导解决问题,但在基础概念(如归一法)上容易出现低级逻辑漏洞,导致一步错步步错。
- 不会强行套用奇怪格式,表现更稳定。
3. 内容质量与风格
- Qwen1.5-1.8B:文采好但失控。
- 写作时修辞丰富、画面感强,但难以控制字数等约束条件。
- 代码/回答倾向于提供完整闭环,主动给出运行结果,对新手友好。
- ChatGLM2-6B:结构稳但平淡。
- 写作风格中规中矩,像标准模板,但能较好地遵守字数和格式约束。
- 回答简洁干练,适合快速获取信息,但缺乏额外的增值服务,要预测结果。
4. 多轮对话能力
- Qwen1.5-1.8B:到第 3 轮就开始忘记前文内容,回答偏离主题
- ChatGLM2-6B:5 轮对话逻辑连贯,能基于前文继续展开

5. 整体差异
- Qwen1.5-1.8B 像是一个背书好但爱加戏的学生,文采好、能蒙对难题,但爱复述问题、逻辑解释瞎编;
- ChatGLM2-6B 像是一个听话但偶尔粗心的助手,不废话、守规矩,但逻辑推导时会犯低级错误。
五、总结
纵观全文,我们回到最初的问题,1.5B 和 6B 差别大吗,对比下来发现差别巨大,但也很微妙;如果我们追求的是能用就行,要在资源受限的边缘设备上跑起来,或者只是做一个简单的文本分类器,Qwen1.5-1.8B是首选。它的代码简洁优美,部署毫无压力,回答的速度也很快。如果你追求的是好用,希望模型能真正帮我们解决逻辑难题、写代码、分析复杂文档,那么请毫不犹豫地为 ChatGLM2-6B或同级别的7B、8B 模型,预留显存。那段略显繁琐的加载代码,是我们为获得更高智商所支付的必要付出。
在本地大模型的江湖里,1.8B 是轻功卓绝的刺客,出手快、隐蔽性强;而 6B 则是内力深厚的剑客,招招沉稳,直击要害。作为开发者,我们的任务不是盲目追求参数量,而是像今天的代码演示一样,看清它们的脾性,将合适的模型,放在最合适的位置上。毕竟,能让业务跑起来的模型,才是好模型。总的来说,没有最好的模型,只有最合适的场景!
附录一:Qwen1.5应用示例代码
# 1. 导入需要的库
from fastapi import FastAPI
from transformers import AutoModelForCausalLM, AutoTokenizer
import uvicorn
from modelscope import snapshot_download
model_name = "qwen/Qwen1.5-1.8B-Chat"
cache_dir = "/home/model"
print("正在下载/校验模型缓存...")
local_model_path = snapshot_download(model_name, cache_dir=cache_dir)
# 生产在线的接口文档,访问方式“/docs”
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
# 2. 初始化FastAPI应用(创建API服务)
app = FastAPI(title="本地大模型开放调用API", description="基于Qwen模型的本地化部署接口")
# 3. 加载模型和Tokenizer(关键:模型会自动下载并加载到CPU)
# AutoModelForCausalLM:加载对话模型权重,AutoTokenizer:处理文字(转换为模型能理解的格式)
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(local_model_path, trust_remote_code=True)
# 4. 定义API接口(POST请求,接收用户提问,返回模型回答)
@app.post("/chat", summary="大模型对话接口")
def chat(question: str):
# 处理用户输入:将文字转换为模型能理解的张量
inputs = tokenizer(question, return_tensors="pt")
# 模型生成回答(max_length:回答最大长度,do_sample:是否随机生成,temperature:随机性程度)
outputs = model.generate(**inputs, max_length=512, do_sample=True, temperature=0.7)
# 将模型输出转换为文字
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 返回结果(JSON格式)
return {"question": question, "answer": answer}
# 5. 启动API服务(监听局域网IP,端口8000)
if __name__ == "__main__":
# host="0.0.0.0":允许局域网内所有设备访问,port=8000:端口号
uvicorn.run(app, host="0.0.0.0", port=8000)
附录二:ChatGLM2应用示例代码
# 1. 导入需要的库
from fastapi import FastAPI
from transformers import AutoTokenizer, AutoModel, AutoConfig
import torch
import uvicorn
from modelscope import snapshot_download
import warnings
warnings.filterwarnings("ignore")
model_name = "ZhipuAI/chatglm2-6b"
cache_dir = "/home/model"
print("正在下载/校验模型缓存...")
local_model_path = snapshot_download(model_name, cache_dir=cache_dir)
# 2. 初始化FastAPI应用(创建API服务)
app = FastAPI(title="ChatGLM2-6B 本地API", description="基于ChatGLM2-6B模型的本地化部署接口")
# 3. 加载模型和Tokenizer(使用AutoModel适配ChatGLM)
print(f"正在加载模型,路径: {local_model_path}")
tokenizer = AutoTokenizer.from_pretrained(local_model_path, trust_remote_code=True)
# 修复ChatGLM配置兼容性问题
config = AutoConfig.from_pretrained(local_model_path, trust_remote_code=True)
# 手动修复配置中缺失的max_length属性
if not hasattr(config, 'max_length'):
config.max_length = config.seq_length if hasattr(config, 'seq_length') else 8192
# 使用AutoModel加载,但禁用一些可能导致问题的特性
try:
model = AutoModel.from_pretrained(
local_model_path,
config=config,
trust_remote_code=True,
low_cpu_mem_usage=False,
torch_dtype=torch.float16
)
except Exception as e:
print(f"加载失败: {e}")
# 尝试直接导入模型类
from transformers import ChatGLMForConditionalGeneration
model = ChatGLMForConditionalGeneration.from_pretrained(
local_model_path,
config=config,
trust_remote_code=True,
torch_dtype=torch.float16
)
print("模型加载完成!")
# 4. 定义API接口(POST请求,接收用户提问,返回模型回答)
@app.post("/chat", summary="ChatGLM2-6B对话接口")
def chat(question: str):
# 处理用户输入:ChatGLM使用特定的prompt格式
response, history = model.chat(tokenizer, question, history=[])
# 返回结果(JSON格式)
return {"question": question, "answer": response}
# 5. 启动API服务(监听局域网IP,端口8000)
if __name__ == "__main__":
# host="0.0.0.0":允许局域网内所有设备访问,port=8000:端口号
print("启动API服务,访问地址: http://0.0.0.0:8000")
uvicorn.run(app, host="0.0.0.0", port=8000)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)