Linux 上本地运行大模型完整指南
详细教程介绍如何在 Linux 系统上用 LLaMA.cpp 部署和运行本地 LLM,包含完整的开发环境配置。
详细教程介绍如何在 Linux 系统上用 LLaMA.cpp 部署和运行本地 LLM,包含完整的开发环境配置。
在这篇文章中,我会分享自己在 Ubuntu 上搭建的本地 AI 环境。无论是个人项目还是专业工作流,我都会使用这套环境,包括本地聊天、Agent 工作流、Coding Agent、数据分析、合成数据集生成等。
在以下场景中,这套环境尤其有用:在本地生成大量合成数据集;通过 LLM 安全处理大量敏感数据;使用本地 Agent,同时避免把私有数据发送给第三方 LLM 提供商;或者完全私密地使用聊天与 RAG。
我们将完成以下工作:
PATH 并持续更新。通过源码编译,可以使用最前沿的 llamacpp 版本,在新功能合并进 master 分支后第一时间使用。我还会介绍自己针对不同工作流使用的模型,以及每个模型的各种高级配置,包括上下文扩展、并行批量推理、多模态、Embedding、Reranking 等。
这是一篇技术实践文章,因此会略过一些基础内容,例如安装和配置基本构建工具、安装 CUDA toolkit、配置 Git 等。如果我遗漏了某些并不直观的配置步骤,或者你在操作过程中遇到问题,请在评论区告诉我。我很乐意提供帮助,也会根据大家对具体配置环节的反馈,逐步补充新信息和更多细节。
VRAM 越多,能够加载的模型就越大。不过,即使你没有与我相同的 GPU,只要使用 NVIDIA GPU 也没问题,仍然可以加载规模更小的模型。只是不要期待较小的 LLM 能在 Agent 和工具调用方面带来很好的效果。
RTX3090 可以将 Q5 量化的 30B Qwen3 模型完整加载到 VRAM 中,推理速度最高可达 140t/s,上下文窗口为 24k tokens;配合一些 Flash Attention 技巧,上下文甚至可以扩展到 110K tokens。
此外,你还需要:
下面是我们将要搭建的整体架构概览。
LlamaCpp 是一款速度非常快且灵活的推理引擎,可以让我们在本地运行 GGUF 格式的 LLM。
git clone git@github.com:ggml-org/llama.cpp.git
cd llama.cpp
为 CUDA 编译 llamacpp:
cmake -B build -DGGML_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DLLAMA_CURL=ON -DGGML_CUDA_FA_ALL_QUANTS=ON
如果你使用其他 GPU,请查看对应的构建指南。
cmake --build build --config Release -j --clean-first
执行完成后,会在 build/bin 文件夹中生成 llama.cpp 的二进制文件。
如果想将 llamacpp 更新到最前沿版本,只需通过 git pull origin master 拉取 master 分支的最新变更,然后运行相同的命令重新编译。
根据你使用的 shell,将下面的内容添加到 bashrc 或 zshrc 配置文件中,这样就能直接在终端里执行 llamacpp 二进制文件:
export LLAMACPP=[PATH TO CLONED LLAMACPP FOLDER]
export PATH=$LLAMACPP/build/bin:$PATH
测试一切是否正常:
llama-server --help
输出应该与预期的帮助信息类似。
接着测试推理是否正常工作:
llama-cli -hf ggml-org/gemma-3-1b-it-GGUF
很好,现在已经可以执行推理了。接下来配置 llama-swap。
llama-swap 是一个轻量级代理服务器,可以为 llama.cpp server 提供自动模型切换能力。它通过一个专用配置文件自动加载和卸载模型,并提供兼容 OpenAI 的 REST API 端点。
从 llama-swap 的 GitHub Releases 页面下载最新版本。
找到名为 llama-swap_159_linux_amd64.tar.gz 的文件。
解压下载的归档文件,并将 llama-swap 可执行文件放到 home 目录下的某个位置,例如 ~/llama-swap/bin/llama-swap。
将它加入 PATH:
export PATH=$HOME/llama-swap/bin:$PATH
在 ~/llama-swap/config.yaml 创建一个暂时为空的配置文件。
在配置 llama-swap 之前,需要先下载几个 GGUF 模型。
首先下载 qwen3-4b 和 gemma3-4b,可在 Hugging Face 的 ggml-org/Qwen3-4B-GGUF 与 ggml-org/gemma-3-4b-it-GGUF 仓库中分别找到以下文件:
Qwen3-4B-Q8_0.ggufgemma-3-4b-it-Q8_0.gguf下载完成后,按照下面的文件夹结构放置 GGUF 文件:
~/models
├── google
│ └── Gemma3-4B
│ └── Qwen3-4B-Q8_0.gguf
└── qwen
└── Qwen3-4B
└── gemma-3-4b-it-Q8_0.gguf
现在已经有了一些 GGUF 文件,接下来创建 llama-swap 配置。
位于 ~/llama-swap/config.yaml 的 llama-swap 配置如下:
macros:
"Qwen3-4b-macro": >
llama-server \
--port ${PORT} \
-ngl 80 \
--ctx-size 8000 \
--temp 0.7 \
--top-p 0.8 \
--top-k 20 \
--min-p 0 \
--repeat-penalty 1.05 \
--no-webui \
--timeout 300 \
--flash-attn on \
--jinja \
--alias Qwen3-4b \
-m /home/[YOUR HOME FOLDER]/models/qwen/Qwen3-4B/Qwen3-4B-Q8_0.gguf
"Gemma-3-4b-macro": >
llama-server \
--port ${PORT} \
-ngl 80 \
--top-p 0.95 \
--top-k 64 \
--no-webui \
--timeout 300 \
--flash-attn on \
-m /home/[YOUR HOME FOLDER]/models/google/Gemma3-4B/gemma-3-4b-it-Q8_0.gguf
models:
"Qwen3-4b": # <-- this is your model ID when calling the REST API
cmd: |
${Qwen3-4b-macro}
ttl: 3600
"Gemma3-4b":
cmd: |
${Gemma-3-4b-macro}
ttl: 3600
现在可以使用下面的命令启动 llama-swap:
llama-swap --listen 0.0.0.0:8083 --config ~/llama-swap/config.yaml
可以在 http://localhost:8083 访问 llama-swap UI。
在这里可以看到所有已配置的模型,也可以手动加载或卸载它们。
下面通过 llama-swap REST API 的 completions endpoint 执行一些推理:
curl -X POST http://localhost:8083/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "hello"
}
],
"stream": false,
"model": "Qwen3-4b"
}' | jq
curl -X POST http://localhost:8083/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "hello"
}
],
"stream": false,
"model": "Gemma3-4b"
}' | jq
你应该会看到类似下面的服务器响应。对于每次请求,llama-swap 都会自动将正确的模型加载到内存中:
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I assist you today? 😊"
}
}
],
"created": 1757877832,
"model": "Qwen3-4b",
"system_fingerprint": "b6471-261e6a20",
"object": "chat.completion",
"usage": {
"completion_tokens": 12,
"prompt_tokens": 9,
"total_tokens": 21
},
"id": "chatcmpl-JgolLnFcqEEYmMOu18y8dDgQCEx9PAVl",
"timings": {
"cache_n": 8,
"prompt_n": 1,
"prompt_ms": 26.072,
"prompt_per_token_ms": 26.072,
"prompt_per_second": 38.35532371893219,
"predicted_n": 12,
"predicted_ms": 80.737,
"predicted_per_token_ms": 6.728083333333333,
"predicted_per_second": 148.63073931406916
}
}
如果你不想每次打开工作站时都手动运行 llama-swap 命令,或者在修改配置后手动重新加载 llama-swap server,可以使用 systemd 自动完成这些工作。
创建以下文件。
如果你没有使用 zsh,请相应调整 ExecStart。
文件路径为 ~/.config/systemd/user/llama-swap.service:
[Unit]
Description=Llama Swap Server
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/zsh -l -c "source ~/.zshrc && llama-swap --listen 0.0.0.0:8083 --config ~/llama-swap/config.yaml"
WorkingDirectory=%h
StandardOutput=journal
StandardError=journal
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
文件路径为 ~/.config/systemd/user/llama-swap-restart.service:
[Unit]
Description=Restart llama-swap service
After=llama-swap.service
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user restart llama-swap.service
这个 unit 会监控 llama-swap 配置文件的变化,并在检测到变更时调用 restart service。
文件路径为 ~/.config/systemd/user/llama-swap-config.path:
[Unit]
Description=Monitor llamaswap config file for changes
After=multi-user.target
[Path]
# Monitor the specific file for modifications
PathModified=%h/llama-swap/config.yaml
Unit=llama-swap-restart.service
[Install]
WantedBy=default.target
启用并启动这些 unit:
sudo systemctl daemon-reload
systemctl --user enable llama-swap-restart.service llama-swap.service llama-swap-config.path
systemctl --user start llama-swap.service
检查服务是否正常运行:
systemctl --user status llama-swap.service
监控 llama-swap server 日志:
journalctl --user -u llama-swap.service -f
每当 llama-swap 配置更新时,llama-swap proxy server 都会自动重启。你可以一边监控日志,一边修改配置文件,以验证这一行为。
如果你已经顺利完成了上述步骤,恭喜!现在可以开始下载和配置自己的模型,并编写自己的配置。你也可以参考作者发布在 GitHub Gist 上、ID 为 dc302228e6628b3099cbafab80ec8998 的配置。
其中包含一些高级配置,例如多模态推理、在同一个模型上执行并行推理、通过 Flash Attention 扩展上下文长度等。
对于这个模型,我建议至少准备 24GB VRAM 😅
下面是我的 llama-swap 配置:
macros:
"Qwen3-Coder-30B-A3B-Instruct": >
llama-server \
--api-key qwen \
--port ${PORT} \
-ngl 80 \
--ctx-size 110000 \
--temp 0.7 \
--top-p 0.8 \
--top-k 20 \
--min-p 0 \
--repeat-penalty 1.05 \
--cache-type-k q8_0 \
--cache-type-v q8_0 \
--no-webui \
--timeout 300 \
--flash-attn on \
--alias Qwen3-coder-instruct \
--jinja \
-m /home/avatsaev/models/qwen/Qwen3-Coder-30B-A3B-Instruct-GGUF/Qwen3-Coder-30B-A3B-Instruct-UD-Q4_K_XL.gguf
models:
"Qwen3-coder":
cmd: |
${Qwen3-Coder-30B-A3B-Instruct}
ttl: 3600
我使用的是 Unsloth 的 Q4 Dynamic quants,并启用了 Flash Attention,同时通过 --cache-type-k 和 --cache-type-v flags 将上下文窗口扩展到 100k tokens。这套配置几乎已经用满 RTX3090 的 24GB VRAM。
你可以在 Qwen Coder 对应的 GGUF 模型仓库中下载这些文件。
作为测试场景,我们来创建一个非常简单的 TypeScript React 应用。
创建一个空项目文件夹 ~/qwen-code-test,并在其中创建 .env 文件,内容如下:
OPENAI_API_KEY="qwen"
OPENAI_BASE_URL="http://localhost:8083/v1"
OPENAI_MODEL="Qwen3-coder"
进入测试目录并启动 Qwen Code:
cd ~/qwen-code-test
qwen
确认模型已经从 .env 文件中正确设置。
我还在 VS Code 中安装了 Qwen Code Companion extension。最终效果就是:一个完全运行在本地的 Coding Agent,直接集成在 VS Code 中 😁
欢迎关注并点赞,也请在评论区告诉我,你准备如何在自己的工作流中使用这套环境。
如果你有任何问题,也可以随时提问。
对于后续操作,你可以考虑屏蔽此人和/或举报滥用行为。