Ollama Python 使用

使用 Python 与 Ollama 交互是通过其 REST API 在本地调用大语言模型(LLM)的一种强大方式,适合自动化任务、构建 AI 应用或批量处理数据。以下是用中文详细讲解如何在 Python 中使用 Ollama,涵盖环境设置、主要 API 端点、示例代码和最佳实践。


1. 前提条件

  • Ollama 已安装:确保已在你的系统(Windows、macOS 或 Linux)上安装了 Ollama。请参考 Ollama 安装指南 或运行以下命令确认:
  ollama --version
  • 启动 Ollama 服务器:API 交互需要服务器运行:
  ollama serve

默认监听地址为 http://localhost:11434

  • Python 环境:需要 Python 3.6+,并安装 requests 库:
  pip install requests
  • 模型已下载:确保已拉取模型(如 llama3):
  ollama pull llama3

2. 核心 API 端点

Ollama 提供三个主要 API 端点,均通过 HTTP POST 请求调用:

  • /api/generate:单次文本生成,适合一次性任务(如回答问题、生成文本)。
  • /api/chat:多轮对话,支持上下文保持,类似聊天机器人。
  • /api/embeddings:生成文本嵌入向量,用于语义搜索或检索增强生成(RAG)。

3. 基本 Python 示例

以下是使用 requests 库调用每个端点的示例代码。运行前确保 Ollama 服务器已启动。

3.1. 单次文本生成(/api/generate

  • 用途:生成单次文本输出,如回答问题、翻译或生成代码。
  • 代码
  import requests
  import json

  url = "http://localhost:11434/api/generate"
  payload = {
      "model": "llama3",
      "prompt": "写一首关于海洋的短诗",
      "stream": False  # 设为 True 启用流式输出
  }

  response = requests.post(url, json=payload)
  if response.status_code == 200:
      result = response.json()
      print(result["response"])
  else:
      print(f"错误:{response.status_code}, {response.text}")
  • 输出示例
  海洋轻声诉说秘密,
  蓝色心脏在星空下呼吸,
  梦境随波浪起舞。
  • 流式输出示例(实时显示):
  response = requests.post(url, json={**payload, "stream": True}, stream=True)
  for line in response.iter_lines():
      if line:
          print(json.loads(line.decode("utf-8"))["response"], end="")

3.2. 多轮对话(/api/chat

  • 用途:支持上下文的对话,适合聊天机器人或连续交互。
  • 代码
  import requests

  url = "http://localhost:11434/api/chat"
  payload = {
      "model": "mistral",
      "messages": [
          {"role": "system", "content": "你是一个友好的助手。"},
          {"role": "user", "content": "日本的首都是哪里?"},
          {"role": "assistant", "content": "日本的首都是东京。"},
          {"role": "user", "content": "东京有什么著名地标?"}
      ],
      "stream": False
  }

  response = requests.post(url, json=payload)
  if response.status_code == 200:
      result = response.json()
      print(result["message"]["content"])
  else:
      print(f"错误:{response.status_code}, {response.text}")
  • 输出示例
  东京的著名地标包括东京塔。

3.3. 生成嵌入向量(/api/embeddings

  • 用途:将文本转为向量,用于语义搜索、分类或 RAG。
  • 代码
  import requests

  url = "http://localhost:11434/api/embeddings"
  payload = {
      "model": "llama3",
      "prompt": "人工智能"
  }

  response = requests.post(url, json=payload)
  if response.status_code == 200:
      embedding = response.json()["embedding"]
      print(embedding[:5])  # 打印向量前5个值
  else:
      print(f"错误:{response.status_code}, {response.text}")
  • 输出示例
  [0.123456, -0.456789, 0.789123, -0.321654, 0.654321]

3.4. 多模态交互(图像处理,需 llava 模型)

  • 用途:使用支持图像的模型(如 llava)描述图片内容。
  • 代码
  import requests
  import base64

  # 读取并编码图片
  with open("image.jpg", "rb") as f:
      img_data = base64.b64encode(f.read()).decode("utf-8")

  url = "http://localhost:11434/api/generate"
  payload = {
      "model": "llava",
      "prompt": "描述这张图片。",
      "images": [img_data],
      "stream": False
  }

  response = requests.post(url, json=payload)
  if response.status_code == 200:
      print(response.json()["response"])
  else:
      print(f"错误:{response.status_code}, {response.text}")
  • 输出示例
  图片展示了一片宁静的海滩,金色沙滩和柔和的海浪在晴朗的蓝天下。

4. 使用 OpenAI 兼容客户端

Ollama 的 API 与 OpenAI 的 API 格式兼容,可使用 openai 库简化调用。

  • 安装 OpenAI 库
  pip install openai
  • 代码示例
  from openai import OpenAI

  client = OpenAI(
      base_url="http://localhost:11434/v1",
      api_key="ollama"  # Ollama 不需要真实 API 密钥
  )

  response = client.chat.completions.create(
      model="llama3",
      messages=[
          {"role": "user", "content": "巴黎的天气如何?"}
      ]
  )
  print(response.choices[0].message.content)
  • 输出示例
  我没有实时天气数据,但10月的巴黎通常凉爽,气温在10-15°C之间。想让我描述一个典型的巴黎场景吗?

5. 高级用法

  • 自定义参数
    通过 options 调整模型行为:
  payload = {
      "model": "llama3",
      "prompt": "写一个故事。",
      "options": {
          "temperature": 0.8,  # 增加创意性
          "top_p": 0.9,       # 核采样
          "num_predict": 200  # 最大 token 数
      }
  }
  • 批量处理
    循环处理多个输入:
  prompts = ["什么是 AI?", "解释机器学习。", "定义深度学习。"]
  for prompt in prompts:
      response = requests.post("http://localhost:11434/api/generate", json={
          "model": "llama3",
          "prompt": prompt,
          "stream": False
      })
      print(f"提示:{prompt}\n响应:{response.json()['response']}\n")
  • RAG 集成
    结合 /api/embeddings 和向量数据库(如 Chroma 或 FAISS):
  import requests
  import numpy as np

  texts = ["AI 改变世界", "机器学习是 AI 的子集"]
  embeddings = []
  for text in texts:
      response = requests.post("http://localhost:11434/api/embeddings", json={
          "model": "llama3",
          "prompt": text
      })
      embeddings.append(response.json()["embedding"])
  # 计算相似度(余弦相似度)
  similarity = np.dot(embeddings[0], embeddings[1]) / (
      np.linalg.norm(embeddings[0]) * np.linalg.norm(embeddings[1])
  )
  print(f"相似度:{similarity}")
  • 与框架集成
    使用 LangChain 或 LlamaIndex:
  from langchain_community.llms import Ollama

  llm = Ollama(model="llama3", base_url="http://localhost:11434")
  response = llm.invoke("讲个笑话。")
  print(response)

6. 最佳实践

  • 错误处理
  try:
      response = requests.post(url, json=payload, timeout=30)
      response.raise_for_status()
      print(response.json()["response"])
  except requests.exceptions.RequestException as e:
      print(f"错误:{e}")
  • 性能优化
  • 小模型(如 phi3)适合低配设备(4-8GB 内存)。
  • 启用 GPU 加速(需 CUDA 或 Metal 支持)。
  • 设置 num_predict 限制输出长度,减少内存占用。
  • 上下文管理
  • 使用 /api/chat 时,通过 messages 维护对话历史。
  • 注意模型上下文限制(如 llama3 默认 8k token)。
  • 安全性
  • 默认 API 仅限本地访问。如需远程访问,设置:
    bash export OLLAMA_HOST=0.0.0.0:11434
    并配置防火墙。
  • 模型管理
    查看运行中的模型:
  response = requests.get("http://localhost:11434/api/ps")
  print(response.json())

7. 常见问题与排查

  • 服务器未运行:确保 ollama serve 已在后台运行。
  • 连接错误:检查 URL (http://localhost:11434) 和端口是否正确。
  • 内存不足:使用量化模型(如 llama3:8b-q4_0)或关闭其他程序。
  • 响应慢:尝试小模型或启用 GPU 加速。
  • 输出截断:增加 num_predict 或检查模型上下文限制。

8. 进阶步骤

  • 探索模型:尝试 mistral(高效)、codellama(代码生成)或 llava(图像处理)。
  • 构建应用:用 Flask 或 FastAPI 创建聊天机器人界面。
  • RAG 开发:结合嵌入向量和向量数据库,构建知识检索系统。

如需特定场景的代码示例(如聊天机器人、RAG 应用、多模态处理)或与 LangChain 等框架的详细整合,请告诉我,我会提供更具体的指导!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注