想象一下,无需复杂的云设置或大量的代码,即可部署先进的人工智能。新一代小型本地大语言模型(LLM)正在将这一愿景变为现实,它们将大型上下文窗口和多模态理解等卓越功能集成到易于访问的软件包中。这些模型为激动人心的低代码/无代码本地LLM应用铺平了道路。本文将带你了解不同的推理引擎,从最用户友好的引擎开始,逐步深入到更强大、可定制的选项,同时涵盖有效的模型交互技术。
系统设置
本文中的说明基于 Windows Subsystem for Linux (WSL),它是 Windows 中运行的 Ubuntu 的一种风格。Linux 子系统运行实际硬件,并且可以通过适当的驱动程序充分利用 CPU 和 GPU。这些说明在原生 Ubuntu 安装上应同样有效,并且需要对其他发行版进行基本修改。虽然并非所有模型和推理方法都绝对需要 GPU,但 LLM 在 GPU 上运行速度更快,并且对于不支持在 CPU 和 GPU 之间拆分层的推理引擎,GPU 的 VRAM 要求可能会很高。
Ollama:快速上手本地LLM
Ollama是让本地LLM在机器上运行的最快方法之一。它是一个开源推理引擎,可以处理运行推理所需的所有步骤。Ollama擅长处理不同的硬件配置,并且可以在可能的情况下利用 GPU。
要安装 Ollama,运行以下命令:
curl -fsSL https://ollama.com/install.sh | sh
此命令运行一个安装脚本,该脚本检查当前的系统配置,下载并安装适当的二进制文件。安装完成后,我们可以使用以下命令运行模型:
ollama run gemma3:4b
这将从 Ollama 下载 Gemma 3 4 Billion 的模型文件,并运行一个基于 CLI 的聊天客户端。你可以从官方支持的模型列表中选择,并在这些模型中选择更大的模型尺寸。CLI 聊天通常仅限于简单的查询,尽管它会保留先前对话的运行上下文。
除了简单的聊天界面外,Ollama 还提供了一个具有 Open AI 兼容 REST API 界面的服务器,可以使用以下命令启动:
ollama serve
有一些很棒的开源基于 Web 的 UI,它们提供了熟悉的 ChatGPT 或 Gemini 风格的界面,可与 Ollama 服务器配合使用。open-webui 就是这样一个 Web UI,可以在这里找到:https://github.com/open-webui/open-webui。
我们还可以使用 curl 来测试 API,如下所示:
curl -X POST http://localhost:11434/api/generate -d '{"model": "gemma3:4b", "prompt": "Tell me a story", "stream": false}'
Ollama 支持的模型列表可在此处找到:https://ollama.com/search
案例分析:快速原型设计
假设你想要快速测试一个创意,例如创建一个简单的问答机器人。使用 Ollama,你只需几分钟即可启动并运行 Gemma 模型,并立即开始与模型交互,评估其在问答任务中的表现。这种快速原型设计能力对于验证想法和探索不同的模型非常有价值。
Llama.cpp:精细控制与模型多样性
当涉及到复杂性和灵活性时,Llama.cpp 是本地推理的下一个级别。设置每个模型需要付出更多的努力,但这使我们可以使用更广泛的模型。Llama.cpp 使用 gguf 模型文件。你可以从不同的来源找到 gguf 模型文件。例如,Google 在 Huggingface 中发布了一组 Gemma 3 模型的量化版本。(Llama.cpp 现在有点用词不当,通常可以运行 gguf 格式的任何模型)。不同的模型有不同的许可要求,你需要接受这些要求才能访问模型文件。在 Huggingface 中注册一个帐户后,该过程非常简单,并且该平台将指导你完成该过程。
https://huggingface.co/collections/google/gemma-3-qat-67ee61ccacbf2be4195c265b
量化:平衡性能与精度
关于量化的说明:通常,模型以更高的精度进行训练,在 Gemma 3 的情况下为 32 位浮点数。这样做是为了数值稳定性,因为训练可能会遇到小梯度或大梯度的精度问题。但是这些 float32 模型非常大,需要大量的内存才能运行,并且在大多数情况下,将参数转换为较低的精度(如 float16、8、4)可以保留大量的精度,同时减少运行推理所需的内存(和推理时间)。这种降低参数精度的方法称为量化,所得的模型称为量化模型。
以下是 Gemma 3 4 Billion 模型的模型大小与量化级别的比较:
| 量化级别 | 模型大小 (GB) |
|—|—|
| Float32 | ~20 |
| Float16 | ~10 |
| Q80 | ~5 |
| Q40 | ~2.5 |
除了能够选择最适合你的用例和硬件需求的量化级别之外,使用 Llama.cpp 的另一个巨大优势是可以访问大量的第三方微调模型库。例如,xLAM 是 Salesforce 开发的一组模型,它们在函数调用或工具使用方面表现出色。这些模型专门用于根据用户查询调用函数,并使用特定数据进行训练以实现结构化输出,例如函数名称和参数。你可以在下面的链接中找到这些基于 Llama 的微调模型列表,如果你需要工具调用,可以使用它们与 Llama.cpp 一起使用。
https://huggingface.co/Salesforce/Llama-xLAM-2-8b-fc-r-gguf/tree/main
现在我们知道了为什么以及何时使用 Llama.cpp,让我们深入了解如何使用它。你可以通过从 Llama.cpp 发布页面获取与你的平台匹配的二进制文件来走预构建路线。但是,我建议从源代码构建它,即使这需要更多的步骤。从源代码构建使我们能够充分利用硬件加速。我将在下面描述这两种方法。
Llama.cpp 来自预构建的二进制文件
你可以在此处找到二进制文件的最新版本:https://github.com/ggml-org/llama.cpp/releases
对于 WSL,我建议使用 llama-b5478-bin-ubuntu-x64.zip。请注意,由于发布平台选项有限,因此不支持 CUDA。下载并解压缩 zip 文件,这将在 build/bin 中提供二进制文件。然后,你可以使用先前下载的 gguf 模型启动 llama-cli。该模型将加载到内存中,并且会出现类似于 Ollama 的 CLI 提示符。
$ cd llama-b5478-bin-ubuntu-x64/build/bin/
$ ./llama-cli -m llm_models/gemma-3-4b-it-q4_0.gguf
== Running in interactive mode. ==
- Press Ctrl+C to interject at any time.
- Press Return to return control to the AI.
- To return control without starting a new line, end your input with '/'.
- If you want to submit another line, end your input with '\'.
- Not using system message. To change it, set a different value via -sys
PROMPT>
Llama.cpp 从源代码构建
安装依赖项和构建工具。
仅 CPU 构建
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build
cmake --build build --config Release
cd build/bin
./llama-cli -m llm_models/gemma-3-4b-it-q4_0.gguf
CUDA 构建
首先为你的平台设置 CUDA sdk 和驱动程序。这些因平台而异,并且还取决于特定的硬件。但是,网上有很多指南可以帮助你进行设置。
使用上述说明克隆 llama.cpp 存储库。启用 CUDA 支持并使用以下命令进行构建。
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release
cd build/bin
./llama-cli --gpu-layers 50 -m llm_models/gemma-3-4b-it-q4_0.gguf
Llama.cpp 具有内置的 API 服务器,类似于 Ollama。以下命令启动服务器:
../llama-server --gpu-layers 50 -m llm_models/gemma-3-4b-it-q4_0.gguf
服务器上的默认端口为 8080。Llama.cpp 还提供一个简单的网页,可以从 http://127.0.0.1:8080/ 访问。如果模型支持,则 Web 界面允许我们上传文件以进行总结并保持上下文。这可以成为一个非常有效的聊天机器人替代方案,适用于更大的模型,例如 gemma-3–27b。
案例分析:定制化部署与性能优化
假设你正在构建一个需要在资源受限的边缘设备上运行的本地LLM应用。使用 Llama.cpp,你可以选择合适的量化级别,并利用 CUDA 等硬件加速技术,以最大限度地提高模型在目标硬件上的性能。此外,你还可以选择针对特定任务进行微调的第三方模型,以进一步优化应用的性能和准确性。
Hugging Face:探索无限可能
如果你正在研究 LLM,Huggingface 是你的朋友。正如你从前面的章节中看到的那样,即使你不使用 Huggingface 库来运行推理,它也是模型的重要资源。Huggingface 上托管了数千个模型、模型变体和微调模型。
首先安装先决条件和依赖项。
pip install transformers torch accelerate bitsandbytes pillow
如果你有受支持的 nvidia GPU,你可以安装 Tensorflow,它用于 GPU 加速。对于仅 CPU 安装,请安装 torch。详细说明可在此处找到:https://huggingface.co/docs/transformers/en/installation
python3 -m pip install tensorflow[and-cuda]
pip install tf-keras
登录到 Huggingface 并为模型创建一个访问令牌。读取令牌应允许我们访问允许的模型。这是生成令牌的 URL:https://huggingface.co/settings/tokens。获得令牌后,可以使用以下命令将其添加到尝试访问模型的计算机:
huggingface-cli login
这将启动一个交互式 CLI,使你可以添加访问令牌。
这是一个使用 huggingface pipeline API 的简单脚本,可以在模型上运行查询。
from transformers import pipeline
import torch
torch._dynamo.config.disable = True
pipe = pipeline(
"text-generation",
model="google/gemma-3-4b-it",
device_map="auto"
)
messages = [
{
"role": "system",
"content": [{"type": "text", "text": "You are a helpful assistant."}]
},
{
"role": "user",
"content": [
{"type": "text", "text": "tell a story"}
]
}]
output = pipe(messages, max_new_tokens=200)
print(output[0]["generated_text"][-1]["content"])
注意:行 torch._dynamo.config.disable = True
特定于 gemma-3 模型,并且是 torch dynamo 问题的解决方法。
与 Ollama 或 Llama.cpp 相比,我们付出了更多的努力,但我们已经使用 Huggingface 运行了推理。但是,前两者到此为止,而 Huggingface 才刚刚开始。我们在这里拥有的是一个最基本形式的 LLM 模型。我们可以拆分图层并使用中间体做一些事情。我们可以使用额外的数据进行微调,直接更改模型权重或使用 LoRA 等技术。让我们看一个例子。
嵌入:理解语义相似性
嵌入是定义嵌入空间的多维向量。LLM 将令牌转换为这些向量,这些向量封装了底层概念。在模型训练期间,这些嵌入向量在嵌入空间内进行组织,以反映每个令牌的含义。例如,最初,单词“hot”和“cold”的向量可能紧密地定位在一起。但是,随着模型的学习,它们应该在空间中进一步分开以表示它们对比的含义。
Gemma-3–4b 模型具有 2560 的嵌入向量大小。通常,嵌入大小越大,模型的能力越强。较大的嵌入维度允许模型捕获细微差别,并且此空间也是模型记忆事物的方式。
Hugging Face Python API 允许从模型中提取嵌入向量。这些嵌入的空间排列反映了语义关系,其中概念上相似的项目定位得更近。两个输入的平均嵌入向量之间的 L2 范数量化了它们的语义相似性。语义相似性的这个概念是各种 AI 应用的基础,包括检索增强生成 (RAG) 和语义搜索。以下代码演示了提取和利用这些嵌入的过程。它比我们到目前为止所做的事情稍微复杂一些,但应该很容易理解。
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
import numpy as np
torch._dynamo.config.disable = True
def setup_model(model_name="google/gemma-3-4b-it"):
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto"
)
return model, tokenizer
def get_embeddings(text, model, tokenizer):
inputs = tokenizer(text, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model(
**inputs,
output_hidden_states=True,
return_dict=True
)
last_hidden_state = outputs.hidden_states[-1]
mean_embedding = last_hidden_state.mean(dim=1)
return mean_embedding
def calculate_l2_distance(embed1, embed2):
embed1_np = embed1.cpu().numpy()
embed2_np = embed2.cpu().numpy()
return np.linalg.norm(embed1_np - embed2_np)
text_list = [
"Tell me a story about a brave knight",
"What is the tallest mountain on earth",
"Tell me a story about a cowardly knight",
"Tell me story about something",
]
model, tokenizer = setup_model()
embeddings = [get_embeddings(text, model, tokenizer) for text in text_list]
print(f"Embedding shape: {embeddings[0].shape}")
print("-" * 50)
print(f"Reference Text: {text_list[0]}")
reference_embedding = embeddings[0]
print("-" * 50)
for i, (text, embedding) in enumerate(zip(text_list[1:], embeddings[1:]), 1):
distance = calculate_l2_distance(reference_embedding, embedding)
print(f"\n{i}: {text}")
print(f"L2 Distance: {distance:.4f}")
运行该程序会产生以下输出。
Embedding shape: torch.Size([1, 2560])
--------------------------------------------------
Reference Text: Tell me a story about a brave knight
--------------------------------------------------
1: What is the tallest mountain on earth
L2 Distance: 63.3646
2: Tell me a story about a cowardly knight
L2 Distance: 14.2378
3: Tell me story about something
L2 Distance: 42.6159
比较显示了参考文本和三个不同短语之间的嵌入距离。短语 1 与讲故事或骑士无关,表现出最大的距离。短语 2 描述了不同类型的骑士,在语义上最接近参考。尽管短语 3 与参考共享了很多单词,但它的含义导致了很大的距离。
能够提取嵌入并非 Huggingface API 独有。Ollama 具有可以执行此操作的 python 绑定,并且 Llama.cpp 具有用于此操作的二进制文件。但是,嵌入只是 Huggingface 提供的灵活性一个方面。API 将每个模型表示为一个类,这使我们可以以多种方式分解它并访问中间体。Huggingface 还有一个非常广泛的微调框架、API 访问数据集等等。我将在以后的文章中介绍这些内容。
案例分析:RAG 应用与知识库构建
假设你正在构建一个基于本地LLM的检索增强生成 (RAG) 应用,用于访问和总结大量的文档。使用 Hugging Face,你可以轻松地提取文档的嵌入,并使用这些嵌入来构建一个向量索引,用于快速检索与用户查询相关的文档片段。然后,你可以将这些片段传递给 LLM,以生成高质量的答案和摘要。
模型大小注意事项
在选择本地LLM时,请记住基本的权衡:具有更多参数的更大的模型通常提供更高的准确性,但代价是推理速度。此速度(通常以每秒令牌数衡量)受许多因素的影响,包括参数计数、量化的级别和类型以及它运行的硬件 (CPU/GPU)。因此,尝试不同的模型大小和配置是找到最适合你的特定用例和性能需求的最佳平衡的关键。
结论
我们介绍了几种在本地运行 LLM 的方法。尽管它们被表示为替代方案,但所有这些方法在模型开发或评估流程中都很有用。Ollama 非常适合轻松测试现成的模型。Llama.cpp 非常适合在特定平台上为特定模型生产推理。Huggingface python 库对于开发(无论是 LLM 之上的应用程序还是修改模型本身的权重)至关重要。
本文的主要目的是让你大致了解当今可以轻松实现的目标,并让你有信心尝试这些本地LLM。这些第一步开启了 AI 应用程序的整个世界,例如 RAG、文档摘要、图像和场景理解等等。我将在以后的文章中以此为基础,介绍其中一些有趣的用例。如果你想探索特定的应用程序,请告诉我。感谢你的阅读。