中文 ▾
获取 API 密钥

Python 中的 Ollama API,然后是托管接口

使用 ollama api python 客户端大约需要十行代码:安装包、启动服务器并调用 chat。本教程涵盖这些内容,然后展示如何通过更改环境变量使同一程序在托管的 OpenAI 兼容接口上运行。

已更新

一条发光的蛇形光线从桌面主机盘旋至服务器云,展示 Python 将本地代码传输到托管环境
聊天窗口通过发光的线缆连接到本地计算机和云服务器

无需卡片。注册后,一键领取 $0.50 免费测试额度(每人限领一次)。

获取 API 密钥

要点

  • pip install ollama,在 11434 端口运行 Ollama 服务器,并使用你已拉取的模型调用 ollama.chat。
  • 流式输出是 stream=True,它会生成带有 message.content 的块。
  • 处理缺失模型的 ResponseError 以及服务器已停止时的 ConnectionError。
  • 要切换到托管环境,请改用 OpenAI SDK,并通过环境变量设置 base URL、密钥和模型。

设置 Python 客户端

首先安装 Ollama 本身,启动它,并从终端拉取一个模型:ollama pull llama3。服务器监听 http://localhost:11434。然后在虚拟环境中安装 Python 包:

python -m venv .venv
source .venv/bin/activate
pip install ollama openai

ollama 包通过 /api 下的 Ollama 原生路由进行通信。openai 包用于本教程的第二部分,目标是一个托管接口。如果你在编码前偏好可视化工具,请参阅 使用 GUI 操作 Ollama 的说明。

在终端中运行 ollama list 来检查安装。如果你的模型出现在那里,Python 就能找到它。如果稍后出现连接错误,服务器可能未运行。

你的第一次聊天调用

这是 ollama api python 基础知识的单段代码:系统消息、用户消息和两个选项。

import ollama

resp = ollama.chat(
    model="llama3",
    messages=[
        {"role": "system", "content": "Answer in one short paragraph."},
        {"role": "user", "content": "What is a context window?"},
    ],
    options={"temperature": 0.4, "num_ctx": 8192},
)
print(resp["message"]["content"])

回复是一个类似字典的对象;文本位于 message.content 中。在 options 中你可以设置生成参数。temperature 控制随机性,num_ctx 设置该请求的上下文长度。Ollama 默认使用一个相对较小的上下文,除非你调高它,这会让粘贴长文档的人感到意外,因为他们得到的回答会忽略开头部分。

对于多轮聊天,保持一个消息列表并自己追加每个回复。Ollama 与大多数聊天 API 一样,在调用之间是无状态的。

流式响应

不启用流式输出时,你需要等待完整答案。使用 stream=True 时,函数返回一个生成器,你可以按到达顺序打印片段:

import ollama

for part in ollama.chat(
    model="llama3",
    messages=[{"role": "user", "content": "Explain recursion with a cooking analogy."}],
    stream=True,
):
    print(part["message"]["content"], end="", flush=True)

每个部分都包含一小段 message.content。最后一部分的 done 设置为 true,并包含计时和 token 计数。对于 Web 应用,通过服务器发送事件或 websocket 将这些片段转发到浏览器。

你实际会遇到的错误

两种故障涵盖了大多数初学者问题。

import ollama

try:
    ollama.chat(model="llama3", messages=[{"role": "user", "content": "hi"}])
except ollama.ResponseError as exc:
    if exc.status_code == 404:
        print("Model missing. Run: ollama pull llama3")
    else:
        raise
except ConnectionError:
    print("Cannot reach Ollama. Is the server running on port 11434?")

来自 ResponseError 的 404 表示模型名称与你拉取的模型不匹配。名称包含标签,因此 llama3 和 llama3:70b 是不同的模型。连接错误意味着服务器未运行,或者你位于一个容器内,其中 localhost 指向容器而非主机。在这种情况下,传递一个具有正确主机的客户端:ollama.Client(host="http://host.docker.internal:11434")。

更多代码模式收集在 常见 Ollama API 错误 中。

同一程序,托管接口

本地模型受你的内存和速度限制。当脚本必须在服务器上运行、处理许多并行作业或使用更大的上下文窗口时,托管接口更容易。诀窍是针对 OpenAI SDK 编写程序,并将基础 URL、密钥和模型视为配置:

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ.get("LLM_BASE_URL", "https://api.ollamansfw.com/v1"),
    api_key=os.environ["LLM_API_KEY"],
)
MODEL = os.environ.get("LLM_MODEL", "uncensored")

def ask(prompt, history=None):
    messages = (history or []) + [{"role": "user", "content": prompt}]
    out = ""
    for chunk in client.chat.completions.create(model=MODEL, messages=messages, stream=True):
        if chunk.choices and chunk.choices[0].delta.content:
            piece = chunk.choices[0].delta.content
            out += piece
            print(piece, end="", flush=True)
    return out

ask("Explain recursion with a cooking analogy.")

对于本地 Ollama,设置 LLM_BASE_URL=http://localhost:11434/v1,LLM_API_KEY=ollama(接受任何非空字符串)和 LLM_MODEL=llama3。对于托管 API,使用上述默认值、你的真实密钥和模型 uncensored。代码中的其他内容无需更改。

在 API 密钥页面 获取密钥。新账户可以一键领取 $0.50 试用额度,无需支付,有效期 7 天。该模型是来自独立提供商的一款开放权重模型,经过调整以在无内容拒绝的情况下回答,适用于合法的成人用途。它仅支持文本,并非任何大型实验室的官方 API。

并行运行多个提示词

一台机器上的本地模型通常一次处理一个请求,因此循环是顺序执行的。托管接口允许并发,这使得批处理工作快得多。将并发请求数保持在你密钥的限制之下:完整密钥为 8 个并发请求,试用密钥为 2 个。

from concurrent.futures import ThreadPoolExecutor
from openai import OpenAI

client = OpenAI(base_url="https://api.ollamansfw.com/v1", api_key="YOUR_KEY")

def summarize(text):
    r = client.chat.completions.create(
        model="uncensored",
        messages=[{"role": "user", "content": "Summarize in one line: " + text}],
        max_tokens=60,
    )
    return r.choices[0].message.content

docs = ["first text", "second text", "third text"]
with ThreadPoolExecutor(max_workers=6) as pool:
    results = list(pool.map(summarize, docs))
print(results)

六个工作线程在 8 的限制之下留有缓冲。如果工作线程收到 429,OpenAI SDK 默认会重试几次,但对于长时间运行的任务,请添加你自己的退避机制。还要记住,每个流式请求都会占用其槽位直到流结束,因此不要在同一个试用密钥上混合长时间流式聊天和大批量任务。

需要规划的区别

  • 没有仅本地可用的选项。 num_ctx 和 keep_alive 在托管端没有意义。上下文窗口为 100,000 个 token,包括提示词和补全。
  • 速率限制。 完整密钥允许 8 个并发请求和每分钟 300 个请求;试用密钥允许 2 个和 60 个。超过此限制你会收到 429,带有 rate_limited 或 concurrency。暂停后重试;在临时过载时,响应包含 Retry-After: 5。
  • 成本。 输入为每 1M 个 token $0.15,输出为每 1M 个 token $0.50。一个发送 2,000 个提示词(每个提示词包含 600 个输入 token 和 400 个输出 token)的脚本花费 2,000 x (600 x $0.15 + 400 x $0.50) / 1M = 2,000 x $0.00029 = $0.58。
  • 计费。 预付额度,从 $20 到 $500,使用加密货币支付(TRC20 上的 USDT 或 Base 上的 USDC)。失败或被拒绝的请求不收费。

若要并排查看接口,请阅读 我们的 API 定价说明 或 文档。

问答

如何在 Python 中调用 Ollama?

安装 ollama 包,启动服务器,拉取模型,然后调用 ollama.chat 方法,传入模型名称和消息列表。

可以在 Ollama 中使用 OpenAI Python SDK 吗?

可以。将 base_url 设置为 http://localhost:11434/v1 并使用任意非空 API 密钥;Ollama 在该地址提供 OpenAI 兼容层。

如何在 Python 中流式输出 Ollama?

向 ollama.chat 传递 stream=True 并遍历返回的块,打印每个块的 message.content。

切换到托管接口时有什么变化?

基础 URL、API 密钥和模型名称。本地选项(如 num_ctx)不适用,你应该处理 429 速率限制响应。