9897 字
49 分钟
本地大模型部署指南

本地大模型部署指南(7B 模型 · Windows / Ubuntu 双系统)#

本指南面向希望在本地部署 7B 参数大语言模型的用户。每个操作系统提供两种方案:简易方案用于快速跑通,学习方案用于理解底层原理。模型统一选用 Qwen2.5-7B(阿里通义千问,中文能力优秀)。


前置知识:你需要了解的基本概念#

在开始部署之前,先理解以下核心概念。这些内容不仅帮助你理解后续每一步在做什么,也是学习大模型技术栈、理解原理、应对面试的基础。


一、模型与架构#

什么是”7B 模型”?

B 代表 Billion(十亿),7B 表示模型有 70 亿个参数。参数本质上是模型在海量文本上训练后学到的数字权重,这些权重决定了模型如何理解和生成语言。参数越多,模型的”知识容量”越大,但需要的计算资源也越多。常见的模型规模有 1B、3B、7B、13B、34B、70B、405B 等,7B 是目前个人电脑能流畅运行的”甜点”尺寸。

什么是 Transformer?

Transformer 是 2017 年 Google 论文《Attention Is All You Need》提出的神经网络架构,当前几乎所有大语言模型都基于它。传统 RNN(循环神经网络)处理序列数据时必须逐词依次处理,无法并行;Transformer 通过自注意力机制让序列中的每个位置都能同时”看到”所有其他位置,从而实现并行计算和长距离依赖建模。

一个标准的 Transformer 由编码器(Encoder)和解码器(Decoder)组成,但现代大语言模型通常只使用解码器部分(Decoder-only 架构),如 GPT、LLaMA、Qwen 都是如此。这类模型的特点是:给定前面的文字,预测下一个 token,逐个生成。

什么是自注意力(Self-Attention)?

自注意力是 Transformer 的核心计算。它的作用是让模型在处理每个词时,能根据上下文动态决定”关注”哪些词。

计算过程可以理解为三个步骤:

  1. 每个 token 生成三个向量:Query(查询,“我在找什么”)、Key(键,“我能提供什么”)、Value(值,“我的实际内容”)
  2. 用 Query 和所有 Key 做点积运算,得到注意力分数,表示”每个词对当前词有多重要”
  3. 将分数通过 Softmax 归一化后,对所有 Value 做加权求和,得到最终输出

这个过程用矩阵运算表示就是:Attention(Q, K, V) = softmax(QK^T / √d_k) V,其中 d_k 是向量维度,除以 √d_k 是为了数值稳定性。

什么是多头注意力(Multi-Head Attention)?

多头注意力是将自注意力并行执行多次,每次使用不同的线性变换(即不同的 Q、K、V 投影矩阵),让模型从不同角度理解语义关系。例如一个”头”可能关注语法结构,另一个”头”关注语义相似性,再一个”头”关注位置关系。最后将所有头的输出拼接并线性变换。

Qwen2.5-7B 使用了 28 个注意力头(GQA 架构,其中 4 个 KV 头),隐藏维度 3584。

什么是 GQA(Grouped-Query Attention)?

GQA 是多头注意力的一种优化变体。标准的多头注意力中,每个头都有独立的 K 和 V 向量,显存开销大。GQA 让多个 Query 头共享同一组 K 和 V 头,在几乎不损失质量的前提下显著减少显存占用和推理时的 KV Cache 大小。LLaMA 2/3、Qwen2/2.5、Mistral 等主流模型都采用了 GQA。

什么是位置编码(Positional Encoding)?

Transformer 的自注意力机制本身不包含位置信息——它把输入当作一个”集合”而非”序列”。位置编码的作用是告诉模型每个 token 在序列中的位置。

主流方案有两种:

  • RoPE(Rotary Position Embedding,旋转位置编码):通过旋转向量来编码相对位置关系,是 LLaMA、Qwen、Mistral 等模型的标配。它的优势是天然支持相对位置,并且可以通过调整旋转频率扩展到更长的上下文
  • ALiBi(Attention with Linear Biases):直接在注意力分数上加一个与距离成比例的偏置,不需要额外的位置编码向量。BLOOM 模型使用此方案

什么是前馈网络(FFN / Feed-Forward Network)?

Transformer 的每一层除了注意力子层外,还有一个前馈网络子层。它由两个线性变换和一个激活函数组成:FFN(x) = W₂ · activation(W₁ · x + b₁) + b₂。前馈网络的作用可以理解为”存储知识”——注意力负责理解上下文关系,FFN 负责调用模型学到的事实知识。

现代模型通常使用 SwiGLU 激活函数替代传统的 ReLU,LLaMA 和 Qwen 都采用了这种设计。

什么是 Decoder-Only 架构?

GPT、LLaMA、Qwen 等模型只使用 Transformer 的解码器部分。它的特点是:生成时每个 token 只能看到它前面的 token(因果注意力,Causal Attention),不能”偷看”后面的。这种架构适合文本生成任务,因为生成过程天然是从左到右逐个进行的。

与之对应的是 Encoder-Only 架构(如 BERT,适合理解类任务)和 Encoder-Decoder 架构(如 T5,适合翻译、摘要等序列到序列任务)。当前大语言模型几乎全部采用 Decoder-Only。


二、训练与对齐#

什么是预训练(Pre-training)?

预训练是在海量无标注文本上训练模型的过程。模型通过”预测下一个 token”这个自监督任务学习语言规律:给定前面的文字,预测下一个最可能的词。通过在数万亿 token 上反复训练,模型学会了语法、常识、推理能力、世界知识等。

预训练是计算密集型任务,一个 7B 模型的预训练通常需要数百到数千张 GPU 运行数周,成本在数十万到数百万美元。这也是为什么大多数人只做推理部署而不自己训练。

什么是 SFT(Supervised Fine-Tuning,监督微调)?

预训练后的模型虽然有强大的语言能力,但不会”像助手一样对话”。SFT 使用人工编写的高质量问答对数据,教模型学会遵循指令、格式化输出、拒绝不当请求等。例如用”请用三句话总结以下文章”这样的指令-回答对来训练。

SFT 是将”语言模型”变成”对话助手”的关键步骤。你使用的 Qwen2.5-7B-Instruct 中的 “Instruct” 就表示这个模型经过了 SFT。

什么是 RLHF(Reinforcement Learning from Human Feedback)?

RLHF 是让模型的输出更符合人类偏好的训练方法。流程是:

  1. 让模型针对同一问题生成多个回答
  2. 人类标注员对这些回答进行排序(哪个更好)
  3. 训练一个”奖励模型”学习人类的偏好判断
  4. 用强化学习(PPO 算法)优化语言模型,使其生成高奖励的回答

RLHF 解决了一个核心问题:模型生成的文本可能语法正确、内容流畅,但不一定是有帮助的、安全的、诚实的。RLHF 让模型学会”什么样的回答是好回答”。

什么是 DPO(Direct Preference Optimization)?

DPO 是 RLHF 的简化替代方案。它不需要训练单独的奖励模型,而是直接从人类偏好数据中优化语言模型。DPO 的数学推导表明,RLHF 的优化目标可以转化为一个简单的分类损失函数,实现更简单、训练更稳定。Qwen2.5、LLaMA 3 等模型都使用了 DPO 进行对齐。

什么是幻觉(Hallucination)?

幻觉指模型生成的内容看起来流畅合理,但实际上是错误的或编造的。例如一本正经地引用一篇不存在的论文,或者给出错误的历史日期。幻觉是当前大语言模型的核心局限之一,产生的根本原因是模型本质上在做概率预测,而非真正的”理解”和”查证”。

减少幻觉的方法包括:RAG(检索增强生成)、要求模型引用来源、使用 CoT(思维链)推理、设置较低的 temperature 等。


三、分词与表示#

什么是 Token(词元)?

Token 是模型处理文本的最小单位。它不等于”词”——一个英文词可能被拆成多个 token(如 “unhappiness” → “un” + “happiness”),一个中文字可能是一个或多个 token(取决于分词器)。模型的输入和输出都是 token 序列。

一个经验法则:英文大约 1 个 token ≈ 4 个字符 ≈ 0.75 个词;中文大约 1-2 个字对应 1 个 token。

什么是分词器(Tokenizer)?

分词器负责在文字和 token IDs 之间转换。它的核心是一个词汇表(vocabulary),记录了所有 token 及其对应的数字 ID。主流的分词算法有:

  • BPE(Byte Pair Encoding,字节对编码):GPT 系列使用。从单个字符开始,反复合并出现频率最高的相邻字符对,直到达到目标词汇表大小。优点是能处理任何未知词
  • WordPiece:BERT 使用。与 BPE 类似,但合并策略不同(基于似然最大化)
  • SentencePiece:支持直接在原始文本上训练,不依赖预分词。LLaMA、Qwen 使用的分词器底层都基于 SentencePiece

Qwen2.5 的词汇表大小为 151,643 个 token,远大于 LLaMA 的 32,000,这让它在中文处理上效率更高。

什么是 Embedding(嵌入/向量表示)?

Embedding 是将离散的 token ID 映射为连续的高维向量。例如 Qwen2.5-7B 将每个 token 映射为一个 3584 维的浮点数向量。这些向量在训练过程中学到语义信息——语义相近的词在向量空间中的距离也近。

Embedding 是模型的第一层,输入 token IDs 经过 Embedding 层后变成向量序列,然后才进入 Transformer 层进行计算。Embedding 矩阵的大小是 vocab_size × hidden_size = 151643 × 3584。


四、推理与优化#

什么是推理(Inference)?

推理就是”运行模型生成回答”的过程。你输入一段文字(Prompt),模型逐个 token 生成输出,每生成一个 token 都需要经过数十层 Transformer 的计算。推理分为两个阶段:

  • 预填充(Prefill):处理整个输入 prompt,计算所有 token 的注意力。这个阶段是计算密集型,可以充分利用 GPU 并行
  • 解码(Decode):逐个生成输出 token。每生成一个新 token 都需要和前面所有 token 做注意力计算。这个阶段是内存带宽密集型,速度瓶颈在于读取 KV Cache

什么是 KV Cache?

在自回归生成过程中,每生成一个新 token 都需要计算它与前面所有 token 的注意力分数。如果不做优化,每生成一个 token 都要重新计算所有前面 token 的 K 和 V 向量,计算量巨大。

KV Cache 的解决方案是:将已经计算过的 K 和 V 向量缓存起来,生成新 token 时只需计算新 token 的 Q 和当前 token 的 K、V,然后和缓存中的历史 K、V 一起做注意力计算。这避免了重复计算,极大加速了推理。

KV Cache 的代价是显存占用。对于 7B 模型、2048 token 上下文,KV Cache 约占 1-2GB 显存。上下文越长,KV Cache 越大。

什么是量化(Quantization)?

模型训练时的参数通常是 32 位或 16 位浮点数(FP32/FP16),每个参数占 2-4 字节。一个 7B 模型在 FP16 下约占 14GB 存储。量化是将这些高精度数字压缩为低精度表示(如 4 位整数),从而将模型体积缩小到 4GB 左右,代价是轻微的质量损失。

常见的量化方法:

  • GPTQ:训练后量化,需要少量校准数据,精度较好
  • AWQ(Activation-aware Weight Quantization):根据激活值分布选择性量化,对重要权重保留更高精度
  • GGUF 量化:llama.cpp 的量化方案,支持从 Q2 到 Q8 多种精度级别,不需要 GPU 即可量化
  • bitsandbytes:动态量化,在加载模型时实时量化,使用最方便

量化级别选择经验:Q4_K_M 是性价比最高的选择,质量损失几乎不可感知,体积缩小约 75%。Q2_K 质量损失明显,仅在显存严重不足时使用。Q8_0 接近原始质量,但体积优势不大。

GPU 与 CPU 的区别?

CPU 擅长复杂逻辑但并行度低(通常 8-16 核),GPU 擅长简单但大规模的并行计算(数千个 CUDA 核心)。大模型推理的核心是矩阵乘法,天然适合 GPU 并行加速。没有 GPU 时可以用 CPU 运行,但速度会慢 5-20 倍。

GPU 推理速度的关键指标是显存带宽(Memory Bandwidth),因为大模型推理的主要瓶颈是读取权重数据而非计算。这也是为什么量化能加速推理——更小的数据类型意味着更少的显存读取量。

什么是 Flash Attention?

Flash Attention 是一种优化注意力计算的技术。标准注意力计算需要将完整的注意力矩阵(大小为序列长度 × 序列长度)存在显存中,对于长序列来说显存开销巨大。Flash Attention 通过分块计算和重计算策略,在不存储完整注意力矩阵的情况下完成计算,将显存使用从 O(n²) 降到 O(n),同时由于减少了显存访问次数,计算速度也更快。

几乎所有现代大模型框架都默认启用了 Flash Attention。

什么是批处理(Batching)与连续批处理(Continuous Batching)?

批处理是指同时处理多个用户请求,将多个输入组成一个批次送入 GPU,充分利用 GPU 的并行能力。传统的批处理要求一个批次中的所有请求都完成后才能处理下一批。

连续批处理(也叫动态批处理)是 vLLM 等框架的核心优化:当批次中某个请求生成完毕时,立即插入新请求,不必等待整个批次完成。这大幅提高了吞吐量。

什么是 PagedAttention?

PagedAttention 是 vLLM 引入的技术,借鉴了操作系统虚拟内存的分页思想。传统方式中,KV Cache 需要连续的显存空间,导致显存碎片化和浪费。PagedAttention 将 KV Cache 分成固定大小的”页”,可以非连续存储,显存利用率接近 100%,吞吐量提升 2-4 倍。


五、应用范式#

什么是 Prompt Engineering(提示词工程)?

Prompt Engineering 是通过精心设计输入文本来引导模型输出更好结果的技术。核心技术包括:

  • Zero-shot:直接提问,不给示例
  • Few-shot:在 prompt 中给几个输入-输出示例,让模型”学会”任务格式
  • CoT(Chain of Thought,思维链):要求模型”一步步思考”,先展示推理过程再给出答案,显著提升推理类任务的准确率
  • System Prompt:系统指令,设定模型的角色、行为约束、输出格式等

Prompt Engineering 是使用大模型最基础也最重要的技能,面试中经常考察。

什么是 RAG(Retrieval-Augmented Generation,检索增强生成)?

RAG 是将外部知识库与大模型结合的技术。流程是:

  1. 将文档切分成片段,通过 Embedding 模型转换为向量,存入向量数据库
  2. 用户提问时,将问题也转换为向量,在向量数据库中检索最相关的文档片段
  3. 将检索到的文档片段和用户问题一起作为 prompt 发送给大模型
  4. 模型基于检索到的上下文生成回答

RAG 解决了大模型的两个核心问题:知识过时(模型只学到训练数据截止日期之前的知识)和幻觉(让模型基于真实文档回答而非”编造”)。

什么是 Agent(智能体)?

Agent 是让大模型不仅能对话,还能自主调用工具、执行操作、完成复杂任务的架构。典型流程是:

  1. 用户给出一个任务目标
  2. 模型分析任务,决定需要调用哪些工具(搜索、代码执行、文件操作等)
  3. 执行工具调用,获取结果
  4. 根据结果决定下一步行动,循环直到任务完成

Agent 是当前大模型应用的前沿方向,也是面试热点。


六、模型文件与格式#

什么是 GGUF 格式?

GGUF(GGML Universal File)是 llama.cpp 项目定义的模型文件格式。它将模型权重、分词器配置、元数据等打包成一个文件,可以直接被 llama.cpp 和 Ollama 加载运行。GGUF 文件包含量化后的权重,文件名中的 Q4_K_M 等标识了量化方案。

什么是 safetensors 格式?

safetensors 是 Hugging Face 推荐的模型权重存储格式。相比传统的 PyTorch .pt/.bin 格式,safetensors 使用纯张量存储(不包含任意 Python 代码),加载更安全(避免 pickle 反序列化漏洞)、加载速度更快(支持内存映射)。Python 生态(transformers、vLLM 等)主要使用此格式。

什么是 Hugging Face Hub?

Hugging Face Hub 是大模型领域的”GitHub”。几乎所有主流开源模型都托管在这里,提供模型下载、版本管理、在线演示等功能。模型页面通常包含模型卡片(Model Card,介绍模型的训练数据、性能、使用方法)、权重文件、配置文件、分词器文件等。

国内访问 Hugging Face 可能较慢,可以使用镜像站 hf-mirror.com。


七、硬件与算力#

什么是 FLOPS 和算力?

FLOPS(Floating Point Operations Per Second)表示每秒浮点运算次数,是衡量硬件计算能力的指标。GPU 的算力通常用 TFLOPS(万亿次/秒)表示。例如 RTX 3090 的 FP16 算力约为 35.6 TFLOPS,RTX 4090 约为 82.6 TFLOPS。

但实际推理速度不仅取决于算力,更取决于显存带宽——大模型推理的瓶颈通常是”读数据”而非”算数据”。

常见 GPU 的显存与适用场景:

  • RTX 3060(12GB):可运行 7B INT4 量化模型
  • RTX 3090 / 4090(24GB):可运行 7B FP16 或 13B INT4 量化模型
  • RTX A5000(24GB):专业卡,适合长时间推理服务
  • A100(40/80GB):数据中心级,可运行 70B 量化模型
  • Apple M 系列(统一内存):16GB 统一内存可运行 7B FP16,32GB 可运行 13B

什么是 CUDA?

CUDA 是 NVIDIA 的 GPU 并行计算平台。PyTorch、llama.cpp 等框架通过 CUDA 调用 GPU 进行矩阵运算。使用 NVIDIA GPU 运行大模型需要安装 CUDA Toolkit 和对应的 cuDNN 库。CUDA 版本需要和 PyTorch 版本匹配。

什么是 ROCm?

ROCm 是 AMD 的 GPU 计算平台,相当于 AMD 版的 CUDA。llama.cpp 和 PyTorch 都支持 ROCm 后端,但兼容性和性能不如 NVIDIA 的 CUDA。如果你使用 AMD 显卡,需要确认你的 GPU 型号在 ROCm 的支持列表中。


八、关键术语速查#

以下是面试和学习中常见的术语,按字母排序,方便查阅:

  • Attention:注意力机制,Transformer 的核心
  • Batch Size:批处理大小,一次处理多少个样本
  • Beam Search:束搜索,一种生成策略,同时维护多个候选序列
  • Checkpoint:模型检查点,训练过程中保存的模型状态
  • Context Window / Context Length:上下文窗口,模型一次能处理的最大 token 数
  • Dropout:训练时随机丢弃部分神经元的正则化技术
  • Epoch:训练时完整遍历一次数据集
  • Fine-tuning:微调,在预训练模型基础上用特定数据继续训练
  • FP16 / BF16:16 位浮点数格式,BF16 的动态范围更大,训练更稳定
  • Gradient:梯度,损失函数对参数的导数,指导参数更新方向
  • Inference:推理,运行模型生成输出
  • Learning Rate:学习率,控制参数更新步长
  • LoRA / QLoRA:低秩适配,用极少参数微调大模型的技术(QLoRA 结合 4 位量化)
  • Loss:损失值,衡量模型预测与真实值的差距
  • MoE(Mixture of Experts):混合专家架构,模型包含多个”专家”子网络,每次只激活部分专家
  • Overfitting:过拟合,模型在训练数据上表现好但泛化能力差
  • Perplexity(PPL):困惑度,衡量语言模型质量的指标,越低越好
  • Temperature:温度参数,控制生成随机性
  • Token/s:每秒生成的 token 数,推理速度的衡量指标
  • Top-k / Top-p:采样策略,从概率最高的 k 个或累积概率前 p 的候选中采样
  • Training:训练,通过数据优化模型参数
  • VRAM:显存,GPU 上的内存

一、Windows 系统部署#

简易部署方案(Ollama · 10 分钟跑通)#

这个方案使用 Ollama,它封装了所有底层细节,你只需要几条命令就能运行模型。

第 1 步:安装 Ollama

打开浏览器访问 https://ollama.com,点击页面上的 Download 按钮,下载 Windows 版安装包(OllamaSetup.exe)。双击运行安装程序,按提示一路点击下一步完成安装。

安装完成后,Ollama 会自动在后台启动一个服务,监听本地 11434 端口。你可以打开任务栏右下角的系统托盘,看到 Ollama 的小图标表示服务已运行。

第 2 步:验证安装

打开 PowerShell 或命令提示符,输入:

Terminal window
ollama --version

如果输出版本号(如 ollama version 0.6.x),说明安装成功。

第 3 步:下载模型

在终端中执行:

Terminal window
ollama pull qwen2.5:7b

Ollama 会自动从仓库下载 Qwen2.5-7B 的 GGUF 量化模型(约 4.7GB),下载过程显示进度条。模型文件会存储在 C:\Users\你的用户名\.ollama\models 目录下。

第 4 步:运行模型

下载完成后,直接启动对话:

Terminal window
ollama run qwen2.5:7b

你会进入一个交互式对话界面,直接输入问题即可。例如输入”用一句话解释什么是量子计算”,模型会逐字输出回答。输入 /bye 退出对话。

第 5 步:调用 API(可选)

Ollama 自动提供兼容 OpenAI 格式的 API 服务。你可以用 Python 调用它:

先安装 openai 库:

Terminal window
pip install openai

创建一个测试脚本 test_api.py:

from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama"
)
response = client.chat.completions.create(
model="qwen2.5:7b",
messages=[
{"role": "user", "content": "你好,请用三句话介绍你自己"}
]
)
print(response.choices[0].message.content)

运行脚本:

Terminal window
python test_api.py

你会看到模型的回复输出在终端中。至此,简易部署完成。


学习部署方案(Python + Transformers · 理解全流程)#

这个方案从零开始,使用 Python 生态手动加载和运行模型。每一步都会解释背后在做什么,适合想深入理解大模型工作原理的学习者。

第 1 步:安装 Python 环境

前往 https://www.python.org/downloads/ 下载 Python 3.10 或 3.11(推荐 3.11)。安装时务必勾选”Add Python to PATH”。

安装完成后验证:

Terminal window
python --version
pip --version

第 2 步:安装 PyTorch(GPU 版本)

PyTorch 是深度学习框架,负责底层的张量计算和 GPU 调度。安装哪个版本取决于你的显卡。

如果你有 NVIDIA 显卡,先确认驱动版本:

Terminal window
nvidia-smi

这会显示你的 GPU 型号和 CUDA 版本。然后访问 https://pytorch.org/get-started/locally/ 选择对应的安装命令。例如 CUDA 12.x 的安装命令是:

Terminal window
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

如果没有独立显卡,安装 CPU 版本:

Terminal window
pip install torch torchvision torchaudio

安装完成后验证 PyTorch 是否能识别 GPU:

Terminal window
python -c "import torch; print(torch.cuda.is_available())"

输出 True 表示 GPU 可用,False 表示将使用 CPU。

第 3 步:安装 Hugging Face 相关库

Hugging Face 是大模型领域的”GitHub”,几乎所有开源模型都托管在这里。transformers 库提供了加载和运行模型的统一接口。

Terminal window
pip install transformers accelerate safetensors sentencepiece protobuf

各库的作用:

  • transformers:Hugging Face 的核心库,提供模型加载、分词器、推理接口
  • accelerate:帮助将大模型分片加载到 GPU 或跨设备分配
  • safetensors:Hugging Face 推荐的安全模型权重格式
  • sentencepiece:分词器的底层实现,Qwen 模型需要它
  • protobuf:分词器配置文件的解析依赖

第 4 步:理解模型下载过程

当你第一次运行代码加载模型时,transformers 会从 Hugging Face 下载模型文件到本地缓存目录(默认在 C:\Users\你的用户名\.cache\huggingface)。

Qwen2.5-7B-Instruct 的完整模型文件包括:

  • 模型配置文件(config.json):定义模型架构参数,如层数、隐藏维度、注意力头数
  • 分词器文件(tokenizer.json 等):将文字切分成 token 并映射为数字 ID
  • 模型权重文件(多个 .safetensors 文件):存放 70 亿个参数的实际数值
  • 生成配置(generation_config.json):默认的生成参数设置

7B 模型的权重在 FP16 精度下约占 14GB 磁盘空间,首次下载需要耐心等待。

如果你的网络访问 Hugging Face 较慢,可以设置镜像源。在 PowerShell 中执行:

Terminal window
$env:HF_ENDPOINT = "https://hf-mirror.com"

第 5 步:编写加载和推理脚本

创建文件 run_model.py,逐步理解每一部分:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# 模型名称,transformers 会自动从 Hugging Face 下载
model_name = "Qwen/Qwen2.5-7B-Instruct"
# 第一步:加载分词器(Tokenizer)
# 分词器负责将文字转换为模型能理解的数字序列(token IDs),以及将输出的数字转回文字
print("正在加载分词器...")
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
# 第二步:加载模型权重
# torch_dtype=torch.float16 使用半精度加载,减少显存占用(14GB → 7GB)
# device_map="auto" 让 accelerate 自动决定将模型放在 GPU 还是 CPU
print("正在加载模型(首次运行需要下载,约 14GB)...")
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
print(f"模型已加载到设备: {model.device}")
print(f"模型参数量: {model.num_parameters() / 1e9:.1f}B")
# 第三步:构造对话输入
# 大模型通常使用"对话模板"来区分系统指令、用户输入和模型回复
messages = [
{"role": "system", "content": "你是一个有帮助的AI助手。"},
{"role": "user", "content": "用简单的语言解释什么是大语言模型,不超过100字。"}
]
# apply_chat_template 会将对话消息转换为模型期望的输入格式
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
# 第四步:分词,将文字转换为 token IDs
inputs = tokenizer(text, return_tensors="pt").to(model.device)
# 第五步:生成回复
# max_new_tokens 限制生成长度,temperature 控制随机性(越低越确定)
print("正在生成回答...\n")
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=512,
temperature=0.7,
top_p=0.9,
do_sample=True
)
# 第六步:解码,将输出的 token IDs 转换回文字
# 只取新生成的部分(去掉输入部分)
response = tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(response)

运行脚本:

Terminal window
python run_model.py

首次运行会下载模型(约 14GB),之后再运行会直接从缓存加载。

第 6 步:理解推理过程中的关键参数

当你看到代码中的 model.generate() 调用时,以下是各参数的含义:

  • max_new_tokens:最多生成多少个新 token。一个中文字大约是 1-2 个 token
  • temperature:控制生成的随机性。0 表示完全确定(每次输出相同),1 表示较高随机性,通常设 0.7
  • top_p:核采样参数。0.9 表示从累积概率前 90% 的候选 token 中采样,过滤掉低概率的奇怪输出
  • do_sample:是否使用采样。设为 False 时使用贪心解码(每次选概率最高的 token),输出更确定但可能重复

第 7 步:观察显存占用

在脚本末尾添加以下代码,查看模型实际占用的显存:

if torch.cuda.is_available():
print(f"GPU 显存占用: {torch.cuda.memory_allocated() / 1024**3:.2f} GB")
print(f"GPU 显存缓存: {torch.cuda.memory_reserved() / 1024**3:.2f} GB")

你会观察到 FP16 精度的 7B 模型大约占用 14-16GB 显存。如果你的显存不足,继续下一步学习量化加载。

第 8 步:使用量化加载(降低显存需求)

安装 bitsandbytes 库,它支持将模型权重量化为 4 位或 8 位:

Terminal window
pip install bitsandbytes

修改加载代码,使用 4 位量化:

from transformers import BitsAndBytesConfig
# 配置 4 位量化
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=quantization_config,
device_map="auto",
trust_remote_code=True
)

量化后显存占用会降到约 4-5GB,8GB 显存的显卡即可流畅运行。代价是输出质量会有轻微下降。

参数解释:

  • load_in_4bit=True:使用 4 位精度加载权重
  • bnb_4bit_compute_dtype:计算时使用的精度,仍然用 FP16 保证计算质量
  • bnb_4bit_quant_type=“nf4”:使用 NormalFloat4 量化方案,比普通 INT4 效果更好
  • bnb_4bit_use_double_quant:二次量化,进一步压缩量化参数本身的开销

第 9 步:理解完整的工作流程

至此你已经走完了大模型部署的完整链路:

  1. 环境准备:安装 Python、PyTorch、transformers
  2. 模型下载:从 Hugging Face 获取模型文件(配置 + 分词器 + 权重)
  3. 分词(Tokenization):将文字转换为数字序列
  4. 前向推理(Forward Pass):数字序列经过 Transformer 的数十层计算
  5. 采样生成(Sampling):从概率分布中选出下一个 token
  6. 解码输出(Decoding):将生成的 token 序列转换回文字

每一步你都已经亲手实现和观察过了。


二、Linux(Ubuntu)系统部署#

简易部署方案(Ollama · 10 分钟跑通)#

第 1 步:安装 Ollama

打开终端,执行官方安装脚本:

Terminal window
curl -fsSL https://ollama.com/install.sh | sh

脚本会自动检测系统环境,下载对应版本的 Ollama 二进制文件,并创建 systemd 服务。安装完成后 Ollama 服务会自动启动。

第 2 步:验证安装

Terminal window
ollama --version

如果需要手动启动或管理服务:

Terminal window
sudo systemctl start ollama # 启动
sudo systemctl stop ollama # 停止
sudo systemctl restart ollama # 重启
sudo systemctl status ollama # 查看状态

第 3 步:下载模型

Terminal window
ollama pull qwen2.5:7b

模型文件会存储在 /usr/share/ollama/.ollama/models 目录下。

第 4 步:运行模型

Terminal window
ollama run qwen2.5:7b

进入对话界面后直接输入问题。输入 /bye 退出。

第 5 步:调用 API(可选)

安装 Python 和 openai 库:

Terminal window
sudo apt update && sudo apt install -y python3 python3-pip
pip3 install openai

创建测试脚本:

Terminal window
cat > test_api.py << 'EOF'
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama"
)
response = client.chat.completions.create(
model="qwen2.5:7b",
messages=[
{"role": "user", "content": "你好,请用三句话介绍你自己"}
]
)
print(response.choices[0].message.content)
EOF

运行:

Terminal window
python3 test_api.py

第 6 步:允许局域网访问(可选)

默认 Ollama 只监听 localhost。如果需要让同一网络下的其他设备访问,编辑服务配置:

Terminal window
sudo systemctl edit ollama

在打开的编辑器中输入:

[Service]
Environment="OLLAMA_HOST=0.0.0.0"

保存后重启服务:

Terminal window
sudo systemctl restart ollama

API 服务即可通过局域网 IP 访问,例如 http://192.168.1.100:11434。


学习部署方案(llama.cpp 编译 + Python Transformers · 理解全流程)#

这个方案分两部分:第一部分从源码编译 llama.cpp,理解 C++ 推理引擎的工作方式;第二部分使用 Python 生态走完完整的模型加载和推理流程。

第一部分:从源码编译 llama.cpp#

第 1 步:理解 llama.cpp 是什么

llama.cpp 是 Georgi Gerganov 开发的纯 C/C++ 推理引擎,最初为在 CPU 上高效运行 LLaMA 模型而设计。它的核心特点是:不依赖 Python、不依赖 PyTorch,通过 C++ 直接实现矩阵运算和模型推理,配合 GGUF 量化格式可以在普通硬件上运行大模型。Ollama 的底层就是 llama.cpp。

第 2 步:安装编译依赖

Terminal window
sudo apt update
sudo apt install -y build-essential cmake git curl
  • build-essential:包含 gcc、g++、make 等 C/C++ 编译工具链
  • cmake:跨平台构建系统,llama.cpp 使用 CMake 管理编译
  • git:用于克隆源码

第 3 步:获取源码

Terminal window
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp

进入目录后,你可以浏览源码结构,了解项目组织方式。核心代码在 src/ 和 include/ 目录下。

第 4 步:编译(CPU 版本)

Terminal window
cmake -B build
cmake --build build --config Release -j$(nproc)
  • cmake -B build:在 build 目录下生成构建文件,自动检测系统环境
  • cmake —build build:执行编译,-j 参数指定并行编译的线程数
  • 编译完成后,可执行文件在 build/bin/ 目录下

第 5 步:编译(GPU 加速版本,如果有 NVIDIA 显卡)

先确认已安装 CUDA Toolkit:

Terminal window
nvcc --version

如果未安装,执行:

Terminal window
sudo apt install -y nvidia-cuda-toolkit

然后带 CUDA 支持重新编译:

Terminal window
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j$(nproc)

-DGGML_CUDA=ON 告诉编译系统启用 CUDA 后端,编译出的程序可以利用 GPU 加速推理。

第 6 步:下载 GGUF 格式模型

llama.cpp 使用 GGUF 格式的模型文件。你需要从 Hugging Face 下载已经转换好的 GGUF 模型。

推荐使用 Qwen2.5-7B-Instruct 的 Q4_K_M 量化版本(约 4.7GB):

Terminal window
# 安装 huggingface-hub 下载工具
pip3 install huggingface-hub
# 下载 GGUF 模型文件
huggingface-cli download Qwen/Qwen2.5-7B-Instruct-GGUF qwen2.5-7b-instruct-q4_k_m.gguf --local-dir models

如果你下载的是整个仓库,文件会在 models/ 目录下。

第 7 步:运行推理

使用编译好的 llama-cli 运行模型:

Terminal window
./build/bin/llama-cli \
-m models/qwen2.5-7b-instruct-q4_k_m.gguf \
-p "你好,请用简单的语言解释什么是人工智能。" \
-n 256 \
--temp 0.7 \
-cnv

参数说明:

  • -m:指定模型文件路径
  • -p:输入的 prompt 文本
  • -n:最多生成的 token 数量
  • —temp:温度参数,控制随机性
  • -cnv:启用对话模式(conversation mode)

你也可以启动一个交互式对话:

Terminal window
./build/bin/llama-cli \
-m models/qwen2.5-7b-instruct-q4_k_m.gguf \
-cnv

第 8 步:启动 HTTP API 服务

llama.cpp 自带一个 HTTP 服务器,兼容 OpenAI API 格式:

Terminal window
./build/bin/llama-server \
-m models/qwen2.5-7b-instruct-q4_k_m.gguf \
--host 0.0.0.0 \
--port 8080

启动后,你可以用 curl 测试:

Terminal window
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5-7b",
"messages": [
{"role": "user", "content": "你好"}
]
}'

至此你已经理解了 llama.cpp 的完整编译和使用流程。你会发现 Ollama 做的事情本质上就是帮你自动化了上面这些步骤。

第二部分:Python + Transformers 完整流程#

第 1 步:安装 Python 环境

Terminal window
sudo apt update
sudo apt install -y python3 python3-pip python3-venv

创建虚拟环境(推荐,避免污染系统 Python 环境):

Terminal window
python3 -m venv ~/llm-env
source ~/llm-env/bin/activate

激活后终端提示符前会出现 (llm-env) 标识。

第 2 步:安装 PyTorch

如果你有 NVIDIA 显卡且已安装 CUDA:

Terminal window
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124

如果是纯 CPU 环境:

Terminal window
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

验证 GPU 是否可用:

Terminal window
python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}'); print(f'GPU: {torch.cuda.get_device_name(0)}' if torch.cuda.is_available() else 'No GPU')"

第 3 步:安装 transformers 及相关库

Terminal window
pip install transformers accelerate safetensors sentencepiece protobuf bitsandbytes

第 4 步:编写完整推理脚本

创建 run_model.py:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "Qwen/Qwen2.5-7B-Instruct"
# 加载分词器
# 分词器的作用是将文字切分成 token(可能是完整的词,也可能是词的一部分)
# 例如 "人工智能" 可能被切分为 ["人工", "智能"] 或 ["人", "工", "智", "能"]
# 每个 token 对应一个数字 ID,模型只认这些数字
print("加载分词器...")
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
# 加载模型
# 如果显存充足(>=16GB),用 FP16 加载
# 如果显存不足(8-12GB),用 4 位量化加载
USE_QUANTIZATION = True # 改为 False 使用完整 FP16 精度
if USE_QUANTIZATION:
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True
)
print("使用 4 位量化加载模型...")
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=quantization_config,
device_map="auto",
trust_remote_code=True
)
else:
print("使用 FP16 加载模型...")
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True
)
print(f"模型加载完成,设备: {model.device}")
# 构造对话
messages = [
{"role": "system", "content": "你是一个有帮助的AI助手。"},
{"role": "user", "content": "用简单的语言解释什么是大语言模型,不超过100字。"}
]
# 将对话转换为模型输入格式
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
# 生成回复
print("生成中...\n")
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=512,
temperature=0.7,
top_p=0.9,
do_sample=True
)
# 解码输出
response = tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(response)
# 显示资源占用
if torch.cuda.is_available():
print(f"\n--- GPU 信息 ---")
print(f"显存占用: {torch.cuda.memory_allocated() / 1024**3:.2f} GB")
print(f"显存缓存: {torch.cuda.memory_reserved() / 1024**3:.2f} GB")

运行:

Terminal window
python3 run_model.py

第 5 步:手动实现一次 Tokenization(加深理解)

创建 understand_tokenizer.py,观察分词器到底在做什么:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct", trust_remote_code=True)
text = "大语言模型是人工智能领域的重大突破"
# 分词
tokens = tokenizer.tokenize(text)
token_ids = tokenizer.encode(text)
print(f"原文: {text}")
print(f"Token 数量: {len(tokens)}")
print(f"分词结果: {tokens}")
print(f"Token IDs: {token_ids}")
print()
# 反向:从 ID 还原文字
decoded = tokenizer.decode(token_ids)
print(f"解码还原: {decoded}")
# 观察特殊 token
print(f"\n特殊 Token:")
print(f" 词表大小: {tokenizer.vocab_size}")
print(f" 开始标记: {tokenizer.bos_token} (ID: {tokenizer.bos_token_id})")
print(f" 结束标记: {tokenizer.eos_token} (ID: {tokenizer.eos_token_id})")
print(f" 填充标记: {tokenizer.pad_token} (ID: {tokenizer.pad_token_id})")

运行后你会看到一段中文是如何被拆分成若干 token 的,每个 token 对应什么数字 ID。这能帮助你理解”token”到底是什么。

第 6 步:手动观察模型结构(加深理解)

创建 inspect_model.py:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_name = "Qwen/Qwen2.5-7B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
output_hidden_states=True
)
# 打印模型结构概览
print("=" * 60)
print("模型结构")
print("=" * 60)
print(f"模型类型: {model.config.model_type}")
print(f"隐藏层维度: {model.config.hidden_size}")
print(f"注意力头数: {model.config.num_attention_heads}")
print(f"键值头数: {model.config.num_key_value_heads}")
print(f"Transformer 层数: {model.config.num_hidden_layers}")
print(f"词汇表大小: {model.config.vocab_size}")
print(f"最大位置编码: {model.config.max_position_embeddings}")
print()
# 打印参数统计
total_params = sum(p.numel() for p in model.parameters())
trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f"总参数量: {total_params:,} ({total_params / 1e9:.2f}B)")
print(f"可训练参数: {trainable_params:,}")
print()
# 打印主要层
print("主要层结构:")
for name, module in list(model.named_children()):
param_count = sum(p.numel() for p in module.parameters())
print(f" {name}: {module.__class__.__name__} ({param_count / 1e6:.1f}M params)")

运行后你会看到模型的具体架构参数:多少层、每层多宽、多少个注意力头。这些数字决定了模型的计算量和能力。

第 7 步:理解显存占用的计算方式

一个 7B 模型在不同精度下的显存需求:

  • FP32(32位浮点):7B × 4 字节 = 28GB
  • FP16(16位浮点):7B × 2 字节 = 14GB
  • INT8(8位量化):7B × 1 字节 = 7GB
  • INT4(4位量化):7B × 0.5 字节 = 3.5GB

实际占用会比理论值稍大,因为还需要存放 KV Cache(注意力计算的中间结果)和运行时开销。这就是为什么 8GB 显存的显卡可以用 INT4 运行 7B 模型,但用 INT8 就会溢出。


三、两种方案对比总结#

简易方案(Ollama)的优势:

  • 安装简单,一条命令搞定
  • 自动管理模型下载和存储
  • 内置 API 服务,开箱即用
  • 自动检测并使用 GPU
  • 适合日常使用和快速验证想法

学习方案的优势:

  • 理解模型文件的结构和格式
  • 理解分词、推理、采样的完整流程
  • 理解量化原理和显存计算
  • 理解 GPU 加速的工作机制
  • 可以灵活调整每一个参数
  • 为后续微调、训练模型打下基础

建议的学习路径:

先用简易方案跑通流程,确认硬件环境没有问题。然后通过学习方案逐步深入理解每个环节。当你理解了底层原理后,回过头来看 Ollama,你会清楚它在每一步帮你做了什么。


四、常见问题排查#

模型下载失败或速度极慢

  • 国内网络访问 Hugging Face 可能不稳定,设置镜像源:
    • Windows PowerShell:$env:HF_ENDPOINT = "https://hf-mirror.com"
    • Linux:export HF_ENDPOINT=https://hf-mirror.com
  • 或使用 huggingface-cli 下载单个文件,避免下载整个仓库

提示 CUDA 内存不足(Out of Memory)

  • 降低量化精度:从 FP16 切换到 INT4 量化
  • 减小 max_new_tokens 的值
  • 关闭其他占用显存的程序(浏览器、游戏等)
  • 在任务管理器或 nvidia-smi 中确认当前显存使用情况

模型加载后推理速度很慢

  • 运行 nvidia-smi 确认 GPU 是否在使用
  • 如果显示 GPU 利用率为 0%,说明模型在 CPU 上运行
  • 检查 PyTorch 是否正确安装了 CUDA 版本
  • llama.cpp 用户确认编译时是否加了 -DGGML_CUDA=ON

Ollama 服务启动失败

  • 检查 11434 端口是否被占用:lsof -i :11434(Linux)或 netstat -ano | findstr 11434(Windows)
  • 查看服务日志:journalctl -u ollama -f(Linux)
  • Windows 用户检查 Windows 防火墙是否拦截

模型输出乱码或重复

  • 确认使用的是 Instruct 版本的模型(如 Qwen2.5-7B-Instruct),而非 Base 版本
  • 检查是否正确使用了对话模板(apply_chat_template)
  • 调整 temperature 和 repetition_penalty 参数
本地大模型部署指南
https://shi01.xyz/posts/本地大模型部署指南/
作者
silent_1968
发布于
2026-11-01
许可协议
CC BY-NC-SA 4.0