> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/mo-xing/tutorials/deepseek-r1-how-to-run-locally.md).

# DeepSeek-R1：如何本地运行

关于如何使用 llama.cpp 运行我们的 DeepSeek-R1 1.58-bit 动态量化版本的指南。

{% hint style="success" %}
请参见 <https://docs.unsloth.ai/basics/deepseek-r1-0528-how-to-run-locally> 以获取更新后的 DeepSeek R1-0528（2025年5月28日版本）
{% endhint %}

## 使用 llama.cpp（推荐）

1. 别忘了 `<｜User｜>` 和 `<｜Assistant｜>` tokens！- 或者使用聊天模板格式化器
2. 获取最新的 `llama.cpp` 在： [github.com/ggml-org/llama.cpp](https://github.com/ggml-org/llama.cpp)。你也可以按照下面的构建说明进行操作。 **对于 Apple Mac / Metal 设备**，设置 `-DGGML_CUDA=OFF` 然后按常规继续——Metal 支持默认开启。

```bash
apt-get update
apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
git clone https://github.com/ggml-org/llama.cpp
cmake llama.cpp -B llama.cpp/build \\
    -DBUILD_SHARED_LIBS=ON -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build llama.cpp/build --config Release -j --clean-first --target llama-quantize llama-cli llama-gguf-split
cp llama.cpp/build/bin/llama-* llama.cpp
```

3. 最好使用 `--min-p 0.05` 来抑制极罕见的 token 预测——我发现这特别适用于 1.58bit 模型，效果很好。
4. 通过以下方式下载模型：

```python
# pip install huggingface_hub hf_transfer
# import os # 可选，用于更快下载
# os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"

from huggingface_hub import snapshot_download
snapshot_download(
  repo_id = "unsloth/DeepSeek-R1-GGUF",
  local_dir = "DeepSeek-R1-GGUF",
  allow_patterns = ["*UD-IQ1_S*"], # 选择 1.58bit 的量化类型 UD-IQ1_S
)
```

6. Q4\_0 K 量化缓存示例 **注意 -no-cnv 会禁用自动对话模式**

```bash
./llama.cpp/llama-cli \\
    --model DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
    --cache-type-k q4_0 \
    -no-cnv --prio 2 \
    --temp 0.6 \\
    --ctx-size 8192 \
    --seed 3407 \
    --prompt "<｜User｜>1+1 等于多少？<｜Assistant｜>"
```

示例输出：

```txt
 <think>
 好吧，所以我需要弄清楚 1 加 1 等于多少。嗯，我该从哪里开始呢？我记得在学校里，加法是最基础的，但我想确保自己真正理解它。
 让我想想，1 加 1。嗯，就是我有一个东西，再加上另一个。也许就像一个苹果加另一个苹果。如果我有一个苹果，别人又给我一个，那我现在就有两个苹果。所以，1 加 1 应该等于 2。这很合理。
 等等，不过数学有时会很棘手。会不会是别的什么？比如在不同的数字系统里也许会不一样？但我觉得这个问题很直接，用的是普通数字，不是二进制、十六进制之类的。
 我也记得在算术里，加法就是把数量合并。所以，如果你有两个 1 的数量，把它们合起来总数就是 2。对，这听起来没错。
 有没有什么情况会让 1 加 1 不等于 2？我想不出来……
```

4. 如果你有一块 GPU（例如 RTX 4090）并且有 24GB 显存，你可以把多层卸载到 GPU 上以获得更快的处理速度。如果你有多块 GPU，可能就能卸载更多层。

```bash
./llama.cpp/llama-cli \\
    --model DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
    --cache-type-k q4_0 \
    -no-cnv --prio 2 \
    --n-gpu-layers 7 \
    --temp 0.6 \\
    --ctx-size 8192 \
    --seed 3407 \
    --prompt "<｜User｜>用 Python 创建一个 Flappy Bird 游戏。<｜Assistant｜>"
```

5. 要测试我们在博客文章中提到的 Flappy Bird 示例，请看这里： <https://unsloth.ai/blog/deepseekr1-dynamic>，我们可以使用我们的 1.58bit 动态量化生成如下第二个示例：

<table data-column-title-hidden data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td>原始 DeepSeek R1</td><td></td><td></td><td><a href="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-3c484081174c631653c8c7bf7e7674f05255f740%2FInShot_20250127_043158375_H8Uu6tyJXYAFwUEIu04Am.gif?alt=media">InShot_20250127_043158375_H8Uu6tyJXYAFwUEIu04Am.gif</a></td></tr><tr><td>1.58bit 动态量化</td><td></td><td></td><td><a href="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-c41eac0fea9362017e94123ee8f9793df21b8e97%2FInShot_20250127_042648160_lrtL8-eRhl4qtLaUDSU87.gif?alt=media">InShot_20250127_042648160_lrtL8-eRhl4qtLaUDSU87.gif</a></td></tr></tbody></table>

使用的提示如下：

{% code overflow="wrap" %}

```
<｜User｜>用 Python 创建一个 Flappy Bird 游戏。你必须包含以下内容：
1. 你必须使用 pygame。
2. 背景颜色应随机选择，并且是浅色。开始时使用浅蓝色。
3. 多次按下 SPACE 键会让小鸟加速。
4. 小鸟的形状应随机选择为正方形、圆形或三角形。颜色应随机选择为深色。
5. 在底部放置一些随机选择为深棕色或黄色的土地。
6. 在右上角显示分数。成功穿过管道且没有撞上时分数增加。
7. 随机间距生成足够空隙的管道。颜色随机为深绿色、浅棕色或深灰色。
8. 失败时，显示最高分。文本要放在屏幕内。按 q 或 Esc 退出游戏。重新开始按 SPACE 键。
最终游戏应放在 Python 的 markdown 代码块中。在最终 markdown 代码块之前检查代码是否有错误并修正它们。<｜Assistant｜>
```

{% endcode %}

要使用这个示例调用 llama.cpp，我们这样做：

```bash
./llama.cpp/llama-cli \\
    --model DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
    --cache-type-k q4_0 \
    -no-cnv --prio 2 \
    --n-gpu-layers 7 \
    --temp 0.6 \\
    --ctx-size 8192 \
    --seed 3407 \
    --prompt "<｜User｜>用 Python 创建一个 Flappy Bird 游戏。你必须包含以下内容：\n1. 你必须使用 pygame。\n2. 背景颜色应随机选择，并且是浅色。开始时使用浅蓝色。\n3. 多次按下 SPACE 键会让小鸟加速。\n4. 小鸟的形状应随机选择为正方形、圆形或三角形。颜色应随机选择为深色。\n5. 在底部放置一些随机选择为深棕色或黄色的土地。\n6. 在右上角显示分数。成功穿过管道且没有撞上时分数增加。\n7. 随机间距生成足够空隙的管道。颜色随机为深绿色、浅棕色或深灰色。\n8. 失败时，显示最高分。文本要放在屏幕内。按 q 或 Esc 退出游戏。重新开始按 SPACE 键。\n最终游戏应放在 Python 的 markdown 代码块中。在最终 markdown 代码块之前检查代码是否有错误并修正它们。<｜Assistant｜>"
```

5. 另外，如果你想将权重合并后用于例如 Ollama，请使用这个脚本：

```bash
./llama.cpp/llama-gguf-split --merge \\
    DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
    merged_file.gguf
```

6. DeepSeek R1 有 61 层。例如，在 24GB GPU 或 80GB GPU 上，你可以在向下取整后预期卸载以下层数（如果超出显存则减 1）：

| 量化      | 文件大小  | 24GB GPU | 80GB GPU | 2x80GB GPU |
| ------- | ----- | -------- | -------- | ---------- |
| 1.58bit | 131GB | 7        | 33       | 全部 61 层    |
| 1.73bit | 158GB | 5        | 26       | 57         |
| 2.22bit | 183GB | 4        | 22       | 49         |
| 2.51bit | 212GB | 2        | 19       | 32         |

### 在 Mac / Apple 设备上运行

对于 Apple Metal 设备，要注意 --n-gpu-layers。如果发现机器内存不足，请降低它。在一台 128GB 统一内存的机器上，你应该可以卸载大约 59 层。

```bash
./llama.cpp/llama-cli \\
    --model DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
    --cache-type-k q4_0 \
    --prio 2 \
    --temp 0.6 \\
    --ctx-size 8192 \
    --seed 3407 \
    --n-gpu-layers 59 \
    -no-cnv \
    --prompt "<｜User｜>用 Python 创建一个 Flappy Bird 游戏。<｜Assistant｜>"
```

### 在 Ollama/Open WebUI 中运行

Open WebUI 在这里制作了一个关于如何运行 R1 的逐步教程： <https://docs.openwebui.com/tutorials/integrations/llm-providers/deepseekr1-dynamic>

\
如果你想使用 Ollama 对 GGUF 进行推理，你需要先把这 3 个 GGUF 分割文件合并成 1 个，如下方代码所示。然后你就需要在本地运行该模型。

```bash
./llama.cpp/llama-gguf-split --merge \\
  DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
	merged_file.gguf
```

## DeepSeek 聊天模板

所有蒸馏版本和主 671B R1 模型都使用相同的聊天模板：

`<｜begin▁of▁sentence｜><｜User｜>1+1 等于多少？<｜Assistant｜>是 2。<｜end▁of▁sentence｜><｜User｜>再解释一下！<｜Assistant｜>`

会强制添加一个 BOS，并且 EOS 会分隔每次交互。为了在推理时抵消双 BOS token，你应该只调用 *tokenizer.encode(..., add\_special\_tokens = False)* 因为聊天模板也会自动添加一个 BOS token。\
对于 llama.cpp / GGUF 推理，你应该跳过 BOS，因为它会自动添加。

`<｜User｜>1+1 等于多少？<｜Assistant｜>`

\<think> 和 \</think> token 有它们各自专门的 token。对于 Qwen 和 Llama 的蒸馏版本，一些 token 被重新映射；而 Qwen 例如没有 BOS token，所以不得不使用 <|object\_ref\_start|> 来替代。\
\
**分词器 ID 映射：**

| Token                     | R1     | 蒸馏 Qwen | 蒸馏 Llama |
| ------------------------- | ------ | ------- | -------- |
| \<think>                  | 128798 | 151648  | 128013   |
| \</think>                 | 128799 | 151649  | 128014   |
| <\|begin\_of\_sentence\|> | 0      | 151646  | 128000   |
| <\|end\_of\_sentence\|>   | 1      | 151643  | 128001   |
| <\|User\|>                | 128803 | 151644  | 128011   |
| <\|Assistant\|>           | 128804 | 151645  | 128012   |
| 填充 token                  | 2      | 151654  | 128004   |

模型中的原始 token：

| Token                 | Qwen 2.5 32B 基础版         | Llama 3.3 70B 指令版                 |
| --------------------- | ------------------------ | --------------------------------- |
| \<think>              | <\|box\_start\|>         | <\|reserved\_special\_token\_5\|> |
| \</think>             | <\|box\_end\|>           | <\|reserved\_special\_token\_6\|> |
| <｜begin▁of▁sentence｜> | <\|object\_ref\_start\|> | <\|begin\_of\_text\|>             |
| <｜end▁of▁sentence｜>   | <\|endoftext\|>          | <\|end\_of\_text\|>               |
| <｜User｜>              | <\|im\_start\|>          | <\|reserved\_special\_token\_3\|> |
| <｜Assistant｜>         | <\|im\_end\|>            | <\|reserved\_special\_token\_4\|> |
| 填充 token              | <\|vision\_pad\|>        | <\|finetune\_right\_pad\_id\|>    |

所有蒸馏版和原始 R1 版本似乎都不小心把填充 token 分配给了 <｜end▁of▁sentence｜>，这大多不是个好主意，尤其是如果你想在这些推理模型之上继续微调的话。这会导致无穷无尽的生成，因为大多数框架会把 EOS token 掩码成 -100。\
\
我们已经用正确的填充 token 修复了所有蒸馏版和原始 R1 版本（Qwen 使用 <|vision\_pad|>，Llama 使用 <|finetune\_right\_pad\_id|>，而 R1 使用 <｜▁pad▁｜> 或我们自己添加的 <｜PAD▁TOKEN｜>。

## GGUF R1 表

<table data-full-width="true"><thead><tr><th>MoE 位数</th><th>类型</th><th>磁盘大小</th><th>准确率</th><th>链接</th><th>详情</th></tr></thead><tbody><tr><td>1.58bit</td><td>UD-IQ1_S</td><td><strong>131GB</strong></td><td>一般</td><td><a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-IQ1_S">链接</a></td><td>MoE 全部 1.56bit。 <code>down_proj</code> MoE 混合 2.06/1.56bit</td></tr><tr><td>1.73bit</td><td>UD-IQ1_M</td><td><strong>158GB</strong></td><td>好</td><td><a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-IQ1_M">链接</a></td><td>MoE 全部 1.56bit。 <code>down_proj</code> MoE 保持在 2.06bit</td></tr><tr><td>2.22bit</td><td>UD-IQ2_XXS</td><td><strong>183GB</strong></td><td>更好</td><td><a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-IQ2_XXS">链接</a></td><td>MoE 全部 2.06bit。 <code>down_proj</code> MoE 混合 2.5/2.06bit</td></tr><tr><td>2.51bit</td><td>UD-Q2_K_XL</td><td><strong>212GB</strong></td><td>最佳</td><td><a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-Q2_K_XL">链接</a></td><td>MoE 全部 2.5bit。 <code>down_proj</code> MoE 混合 3.5/2.5bit</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/zh/mo-xing/tutorials/deepseek-r1-how-to-run-locally.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
