🟡 什么是部署框架?
虽然现在很多模型都是开源的,你不想靠API调用,就想部署到本地给自己用,但是对于大多数开发者和企业而言,将现成的LLM部署到本地并非易事。传统的LLM部署需要深入理解深度学习框架(如PyTorch、TensorFlow)、GPU计算(CUDA、cuDNN)、模型优化技术(量化、剪枝、蒸馏)、Web服务框架(Flask、FastAPI)、容器化技术(Docker、Kubernetes)等等。而且对于不同操作系统、不同硬件平台、不同版本的依赖库之间,常常存在各种兼容性问题,需要花费大量时间进行调试。并且,LLM通常需要大量的计算资源(GPU内存、CPU、磁盘空间),如何高效地管理这些资源,避免资源浪费或冲突,是一个难题。最后部署完成后,还需要进行持续的监控、维护、更新,以确保模型的稳定运行和性能。
部署框架的出现,正是为了解决上述痛点。提供了一种简单、快速、本地化一键部署大模型的方式,让开发者能够专注于应用层面的开发,而无需过多关注底层的技术细节。如果不用Ollama自己部署原始模型,你就按着下面的顺序捣鼓吧
获取模型权重:从公开模型库(如Hugging Face、GitHub)下载原始模型文件(比如LLaMA、Mistral)。
转换格式: 如果不是PyTorch格式(`.pth`或`.pt`),需要用工具(如`transformers`库)转格式
配置环境: 安装PyTorch、CUDA(GPU支持)、相关依赖。处理版本兼容性,确保模型和硬件适配。
加载模型: 编写代码定义模型结构(参考论文),用`torch.load`加载权重。可能需要手动分片加载大模型。
🟡 Ollama的核心组成
Ollama提供了一个统一的命令行界面(CLI)和API接口,用户可通过几条简单的命令完成模型的下载、运行、管理和调用。Ollama的架构可以简化为以下几个核心组件:
- Ollama CLI:用户与Ollama的交互方式,内置一系列命令如
ollama run
、ollama pull
。 - Ollama Server:内置的HTTP服务器,负责处理模型的加载、推理和API请求。
- Model Library:预构建的模型库,包含了各种主流的开源LLM,通过
ollama pull
命令直接下载这些模型。 - Runner:负责执行模型推理的核心组件。配置使用其他推理引擎,如
vLLM
。 - Modelfile:配置文件,用于定义模型的参数、prompt模板、系统指令等。
🔘Ollama Server专题讲解
Ollama Server是整个架构的核心。它实现了两个关键功能:
- 模型管理与推理:负责加载模型到内存、执行推理计算
- API暴露:提供HTTP接口,允许其他应用与模型交互
这里需要给不了解网络通信原理的同学解释一下即使在本地,为什么仍然需要HTTP协议:首先是进程隔离,即Ollama服务器作为独立进程运行,与你的应用程序是分离的。进程间通信(IPC)需要某种标准协议。而HTTP作为通用协议,允许任何语言、任何框架的应用程序轻松集成。并且HTTP协议可以保持本地和远程调用的一致性,简化开发。(当然,也存在其他IPC机制可能比HTTP更高效:比如Unix套接字、windows命名管道)。言归正传,即使都在本地,通信仍然会经过网络协议栈,只是物理层被短路了(通过loopback接口)。就是说:HTTP(应用层)→TCP(传输层)→IP(网络层)→环回接口(链路层)的路径仍然存在,只是跳过了实际的物理传输。
🟡 Ollama的技术原理
- 容器化:Ollama使用Docker将模型运行所需的所有依赖项(如Python、PyTorch、CUDA等)打包在一起。
- 模型量化:Ollama支持4位和8位量化,可以将模型的大小和内存占用显著降低,人人都能玩一把。
- 动态批处理:Ollama的Runner支持动态批处理,根据GPU内存的使用情况自动调整batch size,提高GPU利用率。
- 分页注意力机制: 灵感来源于vLLM 的 PagedAttention。减少显存碎片, 提高大模型推理效率。
- 提供API:Ollama内置了一个HTTP服务器,提供了一个标准的API接口(兼容OpenAI API规范),方便集成。
- 硬件加速: 启动时自动检测可用 GPU ,根据检测到的硬件加载相应的加速库 (如 CUDA, cuDNN, ROCm)。
Ollama支持多种模型格式,会自动处理不同格式之间的转换,用户无需关心模型格式的细节。
- GGUF:专为LLM设计的格式,具有良好的跨平台兼容性和加载速度。Ollama主要使用GGUF格式的模型。
- Safetensors:安全高效的张量存储格式,由Hugging Face开发。
- PyTorch (.bin):PyTorch的原生模型格式。
🟡 Ollama的安装与基本使用
Ollama的安装
Ollama支持多种操作系统,安装过程非常简单:
(1)官网安装程序:从Ollama官网下载Windows安装程序。按照提示完成安装。
(2)Docker安装:直接使用Ollama的Docker镜像:
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
Ollama的基本命令
ollama pull <model_name>
:下载一个模型。(只下载,不立即运行)ollama run <model_name>
:运行一个模型。然后可以在CLI中和它交谈。同时还启动一个API服务端口11434ollama list
:列出本地已有的模型。ollama show <model_name>
:显示一个模型的详细信息,包括Modelfile的内容。ollama cp <source_model> <target_model>
:复制一个模型。ollama rm <model_name>
:删除一个模型。ollama serve
:手动启动Ollama服务(通常不需要,ollama run
会自动启动)。
默认情况下,Ollama启动时只监听localhost:11434
(即127.0.0.1:11434
),这意味着它只接受本机请求。但对于远程访问,localhost
对外部用户是不可见的,别人无法直接连接。如果别人想远程调用你本地运行的Ollama服务,你需要将Ollama绑定到公网可访问的IP(或通过内网穿透等方式暴露出去,然后Ollma的端口默认11434)。
要让别人远程调用,你需要做以下调整:1. 修改Ollama监听地址:默认Ollama只绑定到localhost
,你需要让它监听所有网络接口(0.0.0.0
),这样外部请求才能到达。可以通过设置环境变量OLLAMA_HOST
实现。如果你的设备直接连到公网(比如家用宽带),可以用网站如ifconfig.me
或命令curl ifconfig.me
查看你的公网IP,比如203.0.113.1
。如果你在内网(如公司网络或家用路由器后),需要通过端口映射或内网穿透将服务暴露到公网(后面会讲)。假设你的公网IP是203.0.113.1
,默认端口是11434
,你需要告诉别人访问:http://203.0.113.1:11434/api/generate。 Ollama的API端点(如/api/generate)是官方代码中预定义的,写死在服务器的路由逻辑里的,如果你只做单次文本生成:/api/generate 就够了,它简单直接,适合一次性生成任务,比如生成文章摘要。如果你需要对话功能:/api/chat 更合适,因为它支持多轮对话,保留上下文,类似ChatGPT。当然,还有很多端点这里就不一一列举了奥。
🟡 Ollama与AI框架生态
-
Ollama与PyTorch/TensorFlow
Ollama并非要取代PyTorch或TensorFlow,而是建立在它们之上。Ollama内部使用这些框架来执行模型的计算。PyTorch/TensorFlow负责模型开发(定义模型结构、训练模型)。 Ollama负责模型部署(将训练好的模型加载到本地环境,并提供API服务)。Ollama内部仍然依赖PyTorch(或其他底层框架,如llama.cpp)来执行模型的计算。所以Ollama是PyTorch的部署工具而已。除非你需要修改模型,比如SFT,或者优化算法。否则使用Ollama,你不需要直接与PyTorch或TensorFlow打交道。
-
Ollama与本地AI应用开发框架
Ollama与LangChain、Haystack等RAG框架是互补关系。Ollama可以作为AutoGen、CrewAI等智能体框架的底层LLM引擎 ,Ollama提供本地部署的LLM,并提供API接口,然后LangChain/Haystack通过Ollama提供的API接口,与LLM交互,并结合外部知识库(如向量数据库),构建RAG应用。这种组合的优势在于:因为是Ollma本地部署嘛,LLM和知识库都在本地,数据不出本地,而且本地推理,减少网络延迟。可以将Ollama简单理解为:一个能让你在本地运行的、提供OpenAI兼容API的LLM“服务器”。LangChain、AutoGen、OpenAI Agent SDK等框架本身不包含LLM模型,都是通过API与LLM模型(通常是云端的模型,如OpenAI的GPT系列、Anthropic的Claude系列等)进行交互。而Ollama部署后,就相当于在你的本地机器(或你控制的服务器)上运行LLM,并提供一个本地的API。
-
Ollama与vLLM
Ollama默认使用llama.cpp作为推理引擎,但也可以配置使用vLLM。Ollama和vLLM本质都是模型服务化框架,其设计目标为简化部署而非模型开发。均不支持结构性修改(如架构变更、剪枝等),不适用于深度权重调整或SFT(监督式微调), Ollama的Modelfile提供了一定程度的提示词工程和系统指令调整,也能调整温度,但确实不是真正的模型修改,涉及到微调的时候还是需要导出到PyTorch等训练框架。同样关于工作流和智能体构建,vLLM和Ollama也不是为工作流构建设计的, 构建复杂智能体还需考虑:工具调用、上下文与记忆管理,环境交互能力等等,所以构建完整AI应用流程需要专门的AI模型框架支持,LangChain、Agno、OpenAI Agent SDK等框架填补了这一需求
Ollama支持Windows/macOS/Linux跨平台,5分钟即可启动模型,适合个人开发者或隐私敏感场景(如学术研究),在GTX 1060显卡上即可运行。而vLLM需A100等高端GPU,显存占用更高,专为高性能推理优化设计,采用PagedAttention算法、混合精度等技术,支持多GPU分布式部署,优势在于企业级高并发场景(如日均万次请求),但部署复杂度高,需手动配置CUDA、Kubernetes等环境,在实际应用中,可先用Ollama开发原型,再通过vLLM部署到生产环境。
-
Ollama与Docker/Kubernetes
Ollama本身就支持容器化部署(通过Docker),也可以与Kubernetes集成,实现更高级的部署和管理。单机部署使用Ollama自带的Docker支持即可。集群部署即将Ollama部署到Kubernetes集群中,实现高可用、弹性伸缩等特性。Kubernetes可以根据负载自动扩展Ollama实例的数量,可以自动重启失败的Ollama实例,确保服务的持续可用。
🟡 Ollama的进阶
🔘自定义Modelfile
Modelfile是Ollama的核心特性之一,它允许你定制模型的行为。通过Modelfile,你可以:
- 调整模型参数:如
temperature
、top_p
、top_k
、repeat_penalty
等,控制结果的随机性多样性 - 修改prompt模板:自定义prompt的格式,以适应不同的任务和模型。
- 设置系统指令:给模型一个“角色”或“指令”,引导模型的输出。
- 设置生成停止词: 定义模型在生成文本时遇到什么词就停止。
- 添加自定义工具:将自定义的Python函数集成到Modelfile中,扩展模型的功能。
-
创建一个名为
幽默小助手.Modelfile
的文件:FROM llama3 PARAMETER temperature 0.9 PARAMETER top_p 0.95 SYSTEM "你是一个非常好玩儿的逗比幽默小助手." TEMPLATE """ {{- if .System }}<|start_header|>system<|end_header|> {{ .System }}<|eot_id|>{{- end }}<|start_header|>user<|end_header|> {{ .Prompt }}<|eot_id|> """
-
使用该Modelfile创建一个新模型:
ollama create my-humorous-llama3 -f ./幽默小助手.Modelfile
-
运行新模型:
ollama run my-humorous-llama3
🔘多模型管理
Ollama可以同时运行多个模型,并通过不同的端口提供服务。这在以下场景中非常有用:
- 对比不同模型的性能:你可以同时运行多个不同参数的模型,比较它们的生成效果。
- 为不同的任务使用不同的模型:例如,你可以用一个模型处理通用问题,用另一个模型处理专业领域的问题。
- A/B测试:你可以同时运行同一个模型的不同版本,进行A/B测试。
示例:同时运行Llama 3和Mistral
-
运行Llama 3(默认端口11434):
ollama run llama3
-
运行Mistral,并指定不同的端口(例如11435):
ollama run mistral --port 11435
-
现在,你可以通过不同的端口访问这两个模型:
- Llama 3:
http://localhost:11434
- Mistral:
http://localhost:11435
- Llama 3:
🔘支持模型导出的意义
- Ollama下载模型然后导出
- 下载模型:用Ollama命令下载现成模型:
ollama pull llama3
存储在本地 - 导出模型: 用Ollama导出为PyTorch格式得到一个
.pth
文件,直接是PyTorch可加载的格式。 - 加载模型:在PyTorch环境中加载:
model = torch.load("llama3.pth")
,完事儿。
- 下载模型:用Ollama命令下载现成模型:
Ollama 的核心价值在于提供了一个 本地化的 LLM 运行环境,并提供了一个 与云端 LLM 兼容的 API 接口。Ollama 结合 Agent/RAG 框架的意义,主要是将原本依赖云端 LLM 的应用 迁移到本地,从而获得上述成本、隐私、延迟、可用性等方面的优势。 但凡涉及到对 LLM 本身的修改(如 SFT、继续预训练、模型结构调整等),就 必须 使用 PyTorch、TensorFlow 等底层框架,以及可能的 vLLM(用于推理加速)、DeepSpeed(用于分布式训练)等工具。Ollama 在这种情况下,只能作为 部署和测试修改后模型 的工具。不过好在Ollama支持将模型导出为标准的PyTorch格式.pt
文件。即你可以将Ollama管理的模型导出,然后在PyTorch环境中进行微调,再将微调后的模型重新导入Ollama。
🔘与Web UI集成
Ollama社区提供了Open WebUI等图形化界面,方便非技术人员使用。Open WebUI提供了以下功能:
- 模型管理:直观地查看、下载、删除模型。
- 对话界面:提供了一个类似ChatGPT的对话界面,方便与模型交互。
- 参数调整:可以直接在界面上调整模型参数,如temperature、top_p等。
- 多用户支持:支持多用户同时使用。
🔘高级命令行选项
Ollama CLI还提供了一些高级选项,用于更精细地控制模型的行为:
--verbose
: 显示更详细的日志信息,用于调试。--format
: 指定输出格式(json或text)。ollama run llama3 --format json
--gpu
: 强制使用GPU(如果可用)。 默认自动检测。--num-gpu
: 手动指定使用的 GPU 数量 (当你有多个 GPU 时)。ollama run llama3 --num-gpu 2 # 使用两块 GPU
--system
: 在每次运行模型时设置一个系统消息。--template
: 直接在命令行指定 prompt 模板。
🔘性能监控与调优
- 使用
nvidia-smi
(NVIDIA GPU) 或rocm-smi
(AMD GPU) 监控 GPU 利用率, 显存使用情况。 - 使用
top
或htop
监控 CPU 和内存使用情况。 - Ollama 自身也提供了一些基本的性能指标, 可以通过
--verbose
选项查看。 num_thread
: 在 Modelfile 或命令行中, 可以通过num_thread
参数调整 CPU 线程数。num_gpu
: 如果有多块 GPU, 合理分配num_gpu
可以提高并行度。- 选择合适的量化级别 (4-bit, 8-bit)。
- 调整 batch size (通过 Modelfile 中的
num_ctx
参数间接控制)。
🟡 langserver
🔘Ollma与Langserver发布的服务目的是不同的
维度 | Ollama服务(纯LLM) | AI应用服务(AI构造框架封装) |
---|---|---|
核心功能 | 提供大模型的基础推理能力 | 整合模型、工具(RAG/Agent)、业务逻辑,形成完整工作流 |
技术实现 | 通过HTTP API暴露/generate 等基础接口,仅处理单次请求 | 通过LangServe等框架封装chain.invoke() 逻辑,支持多步骤调用、状态管理、工具调度 |
扩展性 | 仅支持模型参数调整(如temperature) | 可集成向量数据库、函数调用、外部API等,支持复杂交互逻辑 |
使用场景 | 快速验证模型能力或作为底层引擎 | 生产级智能应用(如自动文档分析、多轮对话系统) |
🔘从FastAPI到Langserver
LangServe的方式中没有显式地调用invoke()
方法来执行链。这是因为LangServe采用了一种完全不同的设计理念。在LangServe中,add_routes()
函数会自动为你创建一个API端点,当用户向这个端点发送请求时,LangServe会:
- 自动接收请求数据
- 将数据传递给chain
- 调用chain的invoke方法
- 将结果返回给用户
所以,chain的执行不是在服务器启动时发生的,而是在每次有请求到达API端点时才会触发。这就是为什么你没有看到显式的invoke()
调用。简单来说,传统方式与LangServe方式的区别是:
传统FastAPI方式:
@app.post("/chat")
async def chat(request: ChatRequest):
result = chain.invoke({"label1": request.label1, "label2": request.label2})
return {"content": result}
LangServe方式:
add_routes(app, chain, path="/chain")
在LangServe方式中,invoke()
的调用被封装在LangServe的内部逻辑中,由LangServe在接收到HTTP请求时自动处理。当用户向/chain
端点发送POST请求时,请求体中包含的JSON数据会被作为参数传递给chain.invoke()
方法,然后结果会被返回。这一切都由LangServe自动处理,而不需要你手动编写代码。这就是为什么LangServe能让你的代码如此简洁的原因。这种方式将原本需要显式调用的invoke()
动作转化为对资源的标准HTTP操作(如POST请求),符合RESTful的"统一接口"原则
🟡 云部署后的问题
所以上述讲解后,大家应该理解了,不管是Ollma发布服务,还是Langserver发布服务,区别仅仅在于这个服务自己的能力不同,前者就是普通LLM后者是AI应用,但是就服务而言,现在还没上线啊!只能自己给自己用....
假设自己在云端服务器上部署了一个大模型,并制作了一个可视化问答界面,暴露的端口是 127.0.0.1:6666
。然而,这个端口目前只能通过 SSH 隧道代理访问,外部用户无法直接使用。这是一个典型的本地服务绑定问题,我们先来分析一下。 127.0.0.1
是本地回环地址(localhost),只允许服务器自身访问。如果你的服务绑定在这个地址上,外界(包括你的本机)无法直接连通。如果你想让服务对外可访问,需要将服务绑定到 0.0.0.0
,这样它会监听所有网络接口,外部才能通过服务器的公网IP访问(例如 服务器公网IP:6666
)。因为是我们自己部署的嘛,自然可以通过SSH隧道(如 ssh -L 6666:localhost:6666 user@server_ip
)可以临时解决访问问题,但这显然只能给一些权限极高的开发者用。事实上大模型厂商(如 OpenAI、Google 等)通常通过 API 提供服务,而不是让用户直接访问端口。咱希望自己的大模型也能像这些厂商一样,提供一个对外可用的服务。这意味着需要设计一个基于 HTTP 的 API,并开放公网访问。。即用 API 替代 SSH 隧道,提供标准化的访问方式。
🔘 调用自己的大模型
这是最基础的方式,完全依赖于对 HTTP 协议的理解。假设你的大模型服务已经在服务器上运行,并且监听在 0.0.0.0:6666
,你可以用 Python 的 requests
库发送请求。
客户端 (发送请求)
import requests url = "http://123.45.67.89:6666/predict🧩" # 假设服务器公网IP是 123.45.67.89 data = {"text": "你好,我想问一下今天的天气怎么样?"} response = requests.post(url, json=data) print(response.json()) # 假设服务器返回JSON格式的回答
服务器端 (接收请求)
from fastapi import FastAPI
app = FastAPI()
@app.post("/predict🧩")
async def predict(data: dict):
text = data.get("text")
result = LLM (text)
return {"answer": result}
# 在终端运行:uvicorn your_script:app --host 0.0.0.0 --port 6666
🔘 调用OpenAI的大模型
客户端 (发送请求) 当然,服务端是各家厂商自己实现,咱不用管,而且基本上都是按照OpenAI这个库搞的,能通用。
from openai import OpenAI client = OpenAI(api_key="你的API密钥") response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "你好,我想问一下今天的天气怎么样?"}] ) print(response.choices[0].message.content)
这个库本质上是对 HTTP 请求的封装。它会自动构造一个 POST 请求,发送到 OpenAI 的服务器(如 https://api.openai.com/v1/chat/completions
)。它还处理了认证(通过 API 密钥添加到请求头 Authorization: Bearer 你的密钥
)。对比自己写HTTP请求,用 requests
需要手动写 URL、JSON 数据、请求头。OpenAI 库把这些细节封装成了函数调用,简化了开发。