目录

RTX 3090 本地运行 LLM 实战:vLLM 与 llama.cpp 双引擎对比

RTX 3090 本地运行 LLM 实战:vLLM 与 llama.cpp 双引擎对比

前言

消费级 GPU 跑大语言模型,这事在 2024 年还属于"勉强能跑但体验糟糕"的范畴。到了 2026 年,量化技术、工程优化和推理引擎的共同进步,让这个目标变得真正实用了。

noonghunna/club-3090 是一个刚创建的社区项目(2026-04-28),聚焦于在 RTX 3090(24GB 显存)上本地部署 LLM 的完整配置方案。它不是一个模型,不是一个框架,而是把市面上最优秀的推理引擎和量化方法整合成一套可复现配置的技术手册。项目支持 vLLM 和 llama.cpp 两条技术路线,当前主推 Qwen3.6-27B(INT4 AutoRound 量化版),实测性能达到 127 TPS code(vLLM dual 模式)。

这篇文章从硬件选型、引擎对比、架构设计、核心补丁解析到完整安装流程,系统性地介绍如何在 RTX 3090 上把 LLM 跑出生产级别的体验。


1. 为什么是 RTX 3090

1.1 显存容量是本地 LLM 的天花板

大语言模型对显存的需求主要来自三部分:模型权重、KV Cache 和激活值。以 Qwen3.6-27B 为例,FP16 精度下权重本身就需要 54GB,远超单卡能力。量化是解决这个问题的主要手段——INT4 量化后权重约 13.5GB,加上运行时的 KV Cache 和激活值,24GB 显存的 RTX 3090 刚好能容纳。

RTX 3090 的 24GB GDDR6X 显存是一个关键节点。这个容量在消费级显卡中是天花板级别——RTX 4080 SUPER 只有 16GB,RTX 4090 是 24GB 但价格是 3090 的两倍多,而专业卡(如 A100 40GB)的价格又是 4090 的数倍。对于想在本地或自托管环境中运行中等规模 LLM 的开发者来说,3090 是性价比最优的显存容量选择。

1.2 Ampere 架构的工程现实

RTX 3090 采用 NVIDIA Ampere 架构(sm_86),这在软件层面是有代价的。sm_86 不是 Ada Lovelace 或 Hopper 这些新架构,很多为新架构设计的优化(如 TF32 张量核、新一代 Transformer 引擎)在 Ampere 上不可用或效果打折。

这直接影响了推理引擎的选择:

  • vLLM 的 PagedAttention 在 Ampere 上表现良好,但某些特性(如 flash attention 3)需要 Ada 架构
  • llama.cpp 的 AVX/AVX2/NEON 向量化 天然支持 Ampere,不需要特殊硬件特性
  • 社区为此专门为 Ampere 架构制作了 Genesis 补丁,解决 TurboQuant 在消费级 Ampere GPU 上的兼容性问题

RTX 3090 支持 NVLink(需官方 NVLink 桥接器),但这不是标配。NVLink 在双卡场景下提供了显存聚合和跨卡访问能力——两卡各 24GB 显存通过 NVLink 互通,理论上可以作为一个逻辑整体使用。

不过需要注意,NVLink 的实际带宽(~600 GB/s)相比 PCIe 4.0 x16(~32 GB/s)有巨大优势,但两卡并跑时模型的张量并行(Tensor Parallel)实现复杂度和通信开销会显著增加。club-3090 项目对双卡方案的定位是"多实例并发"而非"单模型张量并行",这个设计决策是务实的。


2. 双引擎架构:vLLM vs llama.cpp

这是整个项目最核心的选择点。两条技术路线代表了两个完全不同的工程哲学。

2.1 vLLM dual:吞吐量优先

vLLM 的核心是 PagedAttention——通过虚拟显存管理机制把 KV Cache 按需分页,避免一次性把全部上下文加载到显存。这个设计让它在高并发场景下有巨大优势。

vLLM dual 模式的实测数据:

  • 生成速度:89-127 TPS(视具体任务而定,code 场景可达 127 TPS)
  • 并发能力:4 路并发 @ 262K 上下文
  • 功能支持:vision(多模态)、tools(函数调用)、MTP(Multi-Token Prediction)、streaming

dual 模式指的是在双卡上各跑一个 vLLM 实例,通过负载均衡实现更高的总吞吐。这不是张量并行,而是两个独立实例的并行处理。

vLLM 的局限性在于它的 CUDA 图(CUDAGRAPH)依赖。某些模型层在启用 CUDAGRAPH 后会出现数值不稳定的"prefill cliffs"——在生成的长文本中间突然出现质量下降。tolist_cudagraph 补丁正是为了解决这个问题。

2.2 llama.cpp single:鲁棒性优先

llama.cpp 是 Georgi Gerganov 的作品,以 CPU+GPU 混合推理著称。它的设计哲学是完全控制底层,不依赖复杂的 CUDA 运行时。

llama.cpp single(单卡)模式的实测数据:

  • 生成速度:约 21 TPS
  • 上下文长度:完整 262K,无任何截断
  • 关键优势:无 prefill cliffs,25K token 工具返回完全正常工作

21 TPS vs 127 TPS,差距是 6 倍。这个数字听起来 llama.cpp 被 vLLM 完胜,但实际情况要复杂得多。

2.3 实际选择建议

场景推荐引擎原因
代码补全、长文本生成vLLM dual127 TPS 的体验差距是决定性的
Agent 函数调用(tools)llama.cpp single25K token 工具返回零截断
超长上下文(>100K)llama.cpp single262K 完整上下文无 prefill cliffs
高并发 API 服务vLLM dual4 路并发能力
追求稳定性不过渡优化llama.cpp single调试友好,无奇怪问题

一个务实的策略是:日常使用用 vLLM dual 追求体验,需要处理超长上下文或复杂函数调用时切换到 llama.cpp single。Docker Compose 架构让这个切换成本很低。


3. 系统架构设计

3.1 Docker Compose 的工程选择

项目采用 Docker Compose 作为部署载体,这个选择有其深层逻辑。

本地 LLM 部署面临的真正难题不是"能不能跑起来",而是"环境能不能复现"。PyTorch 版本、CUDA 版本、transformers 版本、vLLM/llama.cpp 的 git commit——任何一处不匹配都可能导致推理结果不一样或直接跑不起来。把所有依赖打包进 Docker 容器,解决了环境一致性问题。

# 核心结构(简化版)
services:
  vllm-engine:
    build: ./docker/vllm
    runtime: nvidia
    ports:
      - "8020:8000"
    volumes:
      - ./models:/models

  llama-cpp-engine:
    build: ./docker/llama-cpp
    runtime: nvidia
    ports:
      - "8021:8000"
    volumes:
      - ./models:/models

3.2 OpenAI 兼容 API

vLLM 和 llama.cpp 都支持 OpenAI API 格式,这意味着你现有的 LLM 应用几乎不需要修改代码就能切换推理引擎。

# vLLM dual(默认)
curl http://localhost:8020/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Hello"}]}'

# llama.cpp single
curl http://localhost:8021/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"Hello"}]}'

这个 API 兼容性是 club-3090 项目架构设计的核心——它让你可以在 vLLM 和 llama.cpp 之间无缝切换,不需要改一行业务代码。

3.3 一键启动脚本体系

项目提供了三个核心脚本:

# 1. 环境初始化:下载模型、构建 Docker 镜像
bash scripts/setup.sh qwen3.6-27b

# 2. 启动推理服务
bash scripts/launch.sh

# 3. 性能基准测试
bash scripts/bench.sh

setup.sh 会根据参数(目前支持 qwen3.6-27b)下载对应的量化模型权重,构建必要的 Docker 镜像,并配置好目录结构。这个脚本处理了模型下载(通常几十 GB)这个最繁琐的步骤。


4. Qwen3.6-27B 模型解析

4.1 为什么是 Qwen3.6-27B

Qwen3.6-27B 是阿里 Qwen 家族的一个中型模型。27B 参数规模是一个经过验证的"甜点区间":

  • 足够大,能展现出大模型的涌现能力(reasoning、工具使用、长上下文理解)
  • 足够小,INT4 量化后能在 24GB 显存中放下
  • 足够新,Qwen3 系列原生支持工具调用(function calling)和 Agent 模式

Qwen3.6-27B 不是 Qwen 系列的最高配置(还有 Qwen2.5-72B 等更大模型),但在单 RTX 3090 这个硬件约束下,它是目前社区积累最丰富配置的版本。

4.2 INT4 AutoRound 量化

模型量化是把权重从高精度(FP16/BF16)压缩到低精度(INT4/INT8)的过程。量化方法的选择直接影响模型质量和推理速度。

AutoRound 是一种先进的训练后量化(PTQ)方法,它通过可学习的量化参数在少量校准数据上进行微调,显著优于传统的 RTN(Round-to-Nearest)或 GPTQ 方法。其核心思想是把量化网格的边界从固定的四舍五入改为可学习的参数,让模型在压缩后仍能保持较高精度。

club-3090 项目选用的 INT4 AutoRound 量化方案,在 Qwen3.6-27B 上实现了权重约 13.5GB,这个大小刚好能在 RTX 3090 的 24GB 显存中与运行时开销共存。

4.3 MTP Head 的保留

MTP(Multi-Token Prediction)是 Qwen3 系列的一个实验性特性,在部分模型变体中启用。简单来说,它让模型在每个位置同时预测多个 token,然后通过一个"头"(Head)选择最合适的那个输出。这能提升生成质量,但也会增加显存占用。

项目在量化过程中保留了 MTP head,这对工具调用场景特别有意义——MTP 能让模型在函数调用场景中更准确地选择参数。

4.4 262K 上下文的工程实现

Qwen3.6-27B 的上下文长度是 262K tokens,这个数字在消费级硬件上运行是工程奇迹。实现这个能力的关键在于:

  1. 滑动窗口注意力(Sliding Window Attention):不在所有层使用全注意力,只在部分层使用
  2. Flash Attention 的工程优化:减少 HBM 访问次数,降低显存占用
  3. KV Cache 的有效管理:vLLM 的 PagedAttention 或 llama.cpp 的 KV 量化

262K 上下文意味着你可以把一整本《战争与和平》丢给模型处理,这在代码库分析、长文档处理、多轮对话等场景有直接价值。


5. 核心补丁深度解析

项目引用了三个关键技术补丁,这些补丁是让 Qwen3.6-27B 在 RTX 3090 上稳定运行的必要条件。

5.1 Genesis 补丁

Genesis 补丁解决的是一个基础性问题:TurboQuant 量化方案(用于 INT4/INT8 压缩)在消费级 Ampere 架构(sm_86)上的兼容性问题。

TurboQuant 最初是为数据中心 GPU(如 A100/H100)设计的,这些 GPU 有更完整的张量核支持和更大的显存带宽。在 RTX 3090 的 sm_86 架构上直接运行会产生数值溢出或性能崩塌。Genesis 补丁通过重写量化核的部分计算路径,使其适配 Ampere 的硬件特性。

这不是一个 hack,而是一个认真的工程补丁——它在保持量化精度损失最小化的前提下,解决了跨架构部署的兼容性问题。

5.2 tolist_cudagraph 补丁

CUDA Graph 是 NVIDIA 提供的一种优化技术,它把一系列 CUDA 操作打包成一个图,然后一次性提交给 GPU 执行,避免了每次操作都要经过 CUDA 运行时的调度开销。这个优化对推理吞吐量有显著提升。

但 CUDA Graph 在某些模型层上会产生问题——具体表现为生成过程中某个位置突然出现质量下降,这在社区被称为"prefill cliffs"。问题的根源是某些算子在 CUDA Graph 捕获和执行时的数值行为与 eager 模式不一致。

tolist_cudagraph 补丁修改了涉及问题的算子,用等价但 CUDA Graph 兼容的实现替换了原有的 CUDA 代码。启用这个补丁后,vLLM dual 模式可以安全地使用 CUDA Graph 而不出现 prefill cliffs。

5.3 Marlin pad 补丁

Marlin 是一种 INT4/INT8 的 GPU 解包核(kernel),它把压缩后的量化权重高效地还原为 BF16/FP16 进行计算。Marlin 的设计初衷是在保持精度的同时最大化 GPU 利用率。

Marlin pad 补丁处理的是权重矩阵维度不整除时的问题——当模型权重矩阵的维度不是 Marlin 解包核所期望的倍数时,需要在末尾填充(padding)零。pad 补丁确保了这种填充操作在所有层的边界条件下都是正确的。

这三个补丁组合在一起,构成了 RTX 3090 上 Qwen3.6-27B 稳定运行的技术基础。没有这些补丁,模型可以跑起来,但会出现精度问题或性能问题。


6. 完整安装与实测流程

6.1 硬件与环境要求

组件最低要求推荐配置
GPU1× RTX 3090 (24GB)2× RTX 3090 (NVLink)
系统Ubuntu 22.04+Ubuntu 24.04 LTS
Docker20.10+24.x latest
NVIDIA Container Toolkit1.14+最新稳定版
驱动580.x+570.x(CUDA 12.x)

建议一块独立 SSD(至少 100GB 可用空间)用于存储 Docker 镜像和模型权重。

6.2 环境准备

# 1. 确认 NVIDIA 驱动和 Docker 环境
nvidia-smi
docker run --rm --gpus all nvidia/cuda:12.1-runtime-ubuntu22.04 nvidia-smi

# 2. 安装 NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

# 3. 验证 CUDA 容器访问
docker run --rm --gpus all nvidia/cuda:12.1-runtime-ubuntu22.04 \
  nvidia-smi --query-gpu=name,memory.total --format=csv,noheader

6.3 模型下载与服务启动

# 克隆项目
git clone https://github.com/noonghunna/club-3090.git
cd club-3090

# 初始化环境(下载模型 + 构建镜像)
bash scripts/setup.sh qwen3.6-27b

# 启动推理服务
bash scripts/launch.sh

setup.sh 会自动处理 HuggingFace 模型下载(需要访问外网或配置镜像)、Docker 镜像构建和目录初始化。首次运行需要下载约 15-20GB 的量化模型权重。

launch.sh 默认启动 vLLM dual 模式,API 监听在 localhost:8020。如果想启动 llama.cpp single 模式,需要修改脚本参数或切换 docker-compose 配置。

6.4 验证与服务测试

# 健康检查
curl http://localhost:8020/health

# 简单对话测试
curl http://localhost:8020/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.6-27b",
    "messages": [{"role": "user", "content": "用三句话解释量子计算"}]
  }'

# 运行基准测试
bash scripts/bench.sh

bench.sh 会输出一份标准化的性能报告,包括:首 token 延迟、生成速度(TPS)、并发吞吐量、显存占用等核心指标。

6.5 显存监控

# 实时监控显存使用
watch -n 1 nvidia-smi

# 精确测量容器内显存占用
docker exec <container_id> nvidia-smi --query-gpu=memory.used,memory.total --format=csv

RTX 3090 的 24GB 显存在运行 Qwen3.6-27B INT4 时,通常占用 20-22GB,保留 2-4GB 给 KV Cache 和激活值。如果显存占用超过 24GB,会触发 OOM(显存溢出),模型会崩溃或报 CUDA 错误。


7. 适用场景与性能对比总结

7.1 典型使用场景

本地开发与调试:对于正在开发 LLM 应用的开发者,本地运行一个模型能显著加快迭代速度。OpenAI 兼容 API 让你可以直接把应用指向 localhost:8020,不需要网络请求也不产生 API 费用。

隐私敏感数据处理:病历、企业内部文档、法律卷宗——这些数据不适合发送到第三方 API 服务。本地部署解决了数据主权问题。

长上下文处理:llama.cpp single 模式的 262K 完整上下文适合处理整个代码仓库分析、超长文档总结等任务。

离线环境:没有网络连接时,本地模型是唯一选择。Docker 部署方式让整个环境可以打包迁移。

7.2 性能总览

指标vLLM dual (2×3090)llama.cpp single (1×3090)
生成速度89-127 TPS~21 TPS
最大并发4 路 @ 262K1 路 @ 262K
上下文长度262K(工具调用受限)262K(完整)
工具调用稳定性部分场景有截断25K token 完整返回
prefill cliffs有(tolist_cudagraph 补丁后改善)
显存占用~40GB(双卡)~22GB
启动速度较慢较快

7.3 持续演进

这是一个刚创建的项目(2026-04-28),当前版本(2026-04-29)已经有了完整的 vLLM dual 和 llama.cpp single 双路线配置。SGLang 支持在路线图上(目前标注为暂不可用)。项目本身由 noonghunna 的单卡和双卡配置仓库合并而来,社区配置正在快速积累。

值得关注的方向包括:更大量子化精度(INT2)的探索、TensorRT-LLM 后端的接入、以及对 Qwen3.5-32B 等更大模型的支持实验。


8. 快速参考

项目地址https://github.com/noonghunna/club-3090

硬件起点:1× RTX 3090 (24GB) + Ubuntu 22.04 + Docker + NVIDIA Container Toolkit + 驱动 580.x+

启动命令

git clone https://github.com/noonghunna/club-3090.git
cd club-3090
bash scripts/setup.sh qwen3.6-27b
bash scripts/launch.sh

API 端点http://localhost:8020/v1/chat/completions

引擎选择:追求速度选 vLLM dual,追求稳定和超长上下文选 llama.cpp single

RTX 3090 作为本地 LLM 推理的硬件载体,在 2026 年的技术生态下已经是一个非常务实的选择。club-3090 项目把分散在各处工程经验整合成了一套可复现的配置,对想在这个硬件上把 LLM 跑出生产级别体验的开发者来说,是一个值得关注的起点。