VI ▾
Lấy khóa API

API Ollama bằng Python và giải pháp lưu trữ trên đám mây trên đám mây trên đám mây

API Ollama bằng Python chỉ tốn khoảng mười dòng, và cùng cấu trúc mã đó cũng hoạt động với endpoint được lưu trữ. Bài viết này trình bày cả hai và giải thích khi nào nên chọn cái nào.

Cập nhật

Điểm chính

  • Ollama lắng nghe trên cổng 11434 và cung cấp API gốc cùng endpoint /v1 kiểu OpenAI.
  • Gói ollama, requests thuần túy và SDK OpenAI đều hoạt động; SDK OpenAI là khả chuyển nhất.
  • Chuyển sang API được lưu trữ nghĩa là thay đổi URL cơ sở, khóa và tên mô hình.
  • Cục bộ tốt nhất cho công việc ngoại tuyến và phần cứng cố định; được lưu trữ đơn giản hơn khi bạn không có GPU.
Máy tính cục bộ được liên kết bằng cáp phát sáng với máy chủ đám mây, đại diện cho API LLM cục bộ và được lưu trữ

Tóm tắt nhanh

Nếu bạn tìm kiếm ollama api python, bạn thường muốn một trong ba điều: gọi một mô hình chạy trên máy của riêng bạn, truyền phát token từ nó, hoặc làm cho cùng tập lệnh hoạt động ở nơi khác. Ollama cung cấp cho bạn cả ba. Nó chạy máy chủ cục bộ, mặc định tại http://localhost:11434, và bạn giao tiếp với nó bằng gói Python ollama, bằng HTTP thuần túy, hoặc bằng bất kỳ máy khách OpenAI nào trỏ đến đường dẫn /v1 của nó.

Điểm hạn chế là mô hình phải chạy trên phần cứng của bạn. Một máy tính xách tay không có GPU đáng kể sẽ chậm với các mô hình lớn hơn, và một máy chủ không có nó là không phù hợp. Đối với trường hợp đó, API tương thích OpenAI được lưu trữ là tuyến đường dễ dàng hơn, và vì định dạng yêu cầu giống nhau, việc chuyển đổi chỉ tốn ba dòng cấu hình. Cả hai tuyến đường đều được đề cập bên dưới, kèm theo mã bạn có thể dán.

Gọi mô hình cục bộ bằng gói ollama

Cài đặt Ollama, kéo một mô hình và đảm bảo máy chủ đang chạy. Sau đó cài đặt máy khách Python:

pip install ollama
ollama pull llama3.2

Một cuộc gọi trò chuyện cơ bản trông như thế này. Tên mô hình là bất kỳ thứ gì bạn đã kéo; llama3.2 chỉ là một ví dụ.

import ollama

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Explain DNS in two sentences."}],
)
print(response["message"]["content"])

Truyền phát

Truyền stream=True và bạn nhận được một bộ lặp các phần thay vì một phản hồi. Mỗi phần mang một phần của câu trả lời trong message.content.

import ollama

stream = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Write a haiku about servers."}],
    stream=True,
)
for chunk in stream:
    print(chunk["message"]["content"], end="", flush=True)
print()

Trỏ máy khách vào một máy khác

Nếu Ollama chạy trên một máy chủ khác, hãy tạo máy khách với địa chỉ rõ ràng, ví dụ ollama.Client(host="http://192.168.1.20:11434"). Theo mặc định, máy chủ chỉ lắng nghe trên máy cục bộ, vì vậy truy cập từ xa cần một cài đặt rõ ràng ở phía máy chủ. Không công khai nó trên internet mà không có proxy và xác thực phía trước, vì API gốc không có cơ chế kiểm tra khóa riêng.

HTTP thuần túy với requests

Bạn hoàn toàn không cần gói đó. Endpoint trò chuyện gốc là POST /api/chat. Truyền phát là mặc định ở đó, và luồng là JSON phân tách bằng dòng mới, không phải SSE. Đặt "stream": false nếu bạn muốn nhận một đối tượng đơn.

import requests

r = requests.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "llama3.2",
        "messages": [{"role": "user", "content": "Name three HTTP status codes."}],
        "stream": False,
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["message"]["content"])

Đặt thời gian chờ hào phóng. Yêu cầu đầu tiên sau khi kéo phải tải mô hình vào bộ nhớ, và điều đó có thể mất lâu hơn nhiều so với các yêu cầu sau đó.

Đọc luồng bằng tay chỉ tốn thêm vài dòng. Gọi requests.post(..., stream=True), lặp qua r.iter_lines(), bỏ qua các dòng trống và chạy json.loads trên mỗi dòng. Mỗi đối tượng chứa một phần nhỏ của phản hồi, và đối tượng cuối cùng có "done": true. Điều này hữu ích trong một vùng chứa tối thiểu nơi bạn muốn tránh cài đặt thêm gói, và nó làm rõ những gì thư viện làm cho bạn. API được lưu trữ truyền phát khác biệt, dưới dạng các dòng SSE bắt đầu bằng data:, đó là một lý do nữa để để SDK OpenAI phân tích luồng cho bạn trong mã khả chuyển.

Sử dụng SDK OpenAI với Ollama

Ollama cũng hiển thị một endpoint kiểu OpenAI dưới /v1. Điều đó có nghĩa là gói openai chính thức hoạt động, và hầu hết phần mềm cho phép bạn đặt URL cơ sở tùy chỉnh cũng hoạt động. Khóa được SDK yêu cầu nhưng bị bỏ qua bởi Ollama cục bộ, vì vậy bất kỳ chuỗi nào cũng được.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Give me a one-line summary of TCP."}],
)
print(resp.choices[0].message.content)

Đây là dạng hữu ích nhất, vì nó tách mã của bạn khỏi máy chủ. Cùng một hàm có thể giao tiếp với mô hình cục bộ ngày hôm nay và với thứ gì đó khác vào ngày mai, đó là phần tiếp theo.

Cùng mã với API được lưu trữ

Tùy chọn được lưu trữ ở đây là API tương thích OpenAI với một mô hình duy nhất, uncensored, do một nhà cung cấp độc lập chạy và được tinh chỉnh để trả lời mà không từ chối nội dung cho việc sử dụng hợp pháp của người trưởng thành. Nó chỉ dành cho văn bản. URL cơ sở là https://api.ollamaapi.cc/v1, và bạn xác thực bằng khóa Bearer từ trang khóa API.

Đây là một phiên bản đọc mục tiêu của nó từ các biến môi trường, với các giá trị được lưu trữ làm mặc định. Để quay lại máy chủ cục bộ của bạn, hãy xuất hai biến và không thay đổi gì khác.

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("LLM_BASE_URL", "https://api.ollamaapi.cc/v1"),
    api_key=os.getenv("LLM_API_KEY", "YOUR_API_KEY"),
)
MODEL = os.getenv("LLM_MODEL", "uncensored")

resp = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "List four uses of a message queue."},
    ],
    temperature=0.7,
)
print(resp.choices[0].message.content)

Đối với các chạy cục bộ, đặt LLM_BASE_URL=http://localhost:11434/v1, LLM_API_KEY=ollama và LLM_MODEL=llama3.2. hướng dẫn bắt đầu nhanh có cùng thiết lập trong curl và Node.

Truyền phát, chế độ JSON và công cụ ở phía lưu trữ

Endpoint được lưu trữ hỗ trợ truyền phát qua SSE, chế độ JSON, gọi công cụ và các tham số lấy mẫu thông thường (temperature, top_p, stop, seed và các penalty). Truyền phát với SDK là vòng lặp giống nhau mà bạn sẽ viết cho bất kỳ máy chủ kiểu OpenAI nào:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Tell a two-paragraph story about a lighthouse."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Đối với đầu ra có cấu trúc, đặt response_format={"type": "json_object"} và nói trong prompt rằng bạn muốn JSON. Luôn phân tích cú pháp bên trong khối try; một mô hình vẫn có thể trả về thứ gì đó bạn không mong đợi.

Một khác biệt so với sử dụng cục bộ ảnh hưởng đến mã: giới hạn. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút, và một yêu cầu truyền phát giữ slot của nó cho đến khi luồng kết thúc. Nếu bạn chạy song song bằng các luồng, hãy giới hạn pool ở mức 8 và thử lại khi nhận HTTP 429 bằng cách sử dụng tiêu đề Retry-After khi nó có mặt.

Duy trì hội thoại

Cả endpoint trò chuyện cục bộ và được lưu trữ đều không nhớ gì giữa các cuộc gọi. Máy chủ chỉ thấy các thông báo bạn gửi, vì vậy bot trò chuyện là một danh sách mà bạn thêm vào và gửi lại. Mẫu này giống nhau cho cả hai mục tiêu, đó là một lý do nữa để giữ máy khách kiểu OpenAI làm mặc định của bạn.

history = [{"role": "system", "content": "You are a helpful assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(model=MODEL, messages=history)
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    return answer

print(ask("Pick a name for a hiking app."))
print(ask("Give me a tagline for it."))

Hai ghi chú thực tế. Thứ nhất, các mô hình cục bộ có độ dài ngữ cảnh mà bạn đặt và bộ nhớ phải giữ; nếu lịch sử phát triển vượt quá nó, các lượt chuyển cũ hơn bị cắt hoặc cuộc gọi thất bại, tùy thuộc vào cài đặt. Mô hình được lưu trữ chấp nhận cửa sổ 100.000 token bao gồm phần hoàn thành, điều đó nhiều hơn hầu hết các cuộc trò chuyện cần, nhưng lịch sử dài vẫn tốn token đầu vào trên mỗi lượt. Thứ hai, một khi lịch sử trở nên dài, hãy tóm tắt các lượt chuyển cũ nhất thành một thông báo ngắn thay vì gửi lại tất cả chúng. Điều đó giữ độ trễ và chi phí ổn định trên cả hai máy chủ.

Thử lại một cách lịch sự

Trên API được lưu trữ, quá tải tạm thời trả về HTTP 429 với tiêu đề Retry-After: 5. Một trình bao bọc nhỏ xử lý nó:

import time
from openai import RateLimitError

def chat_with_retry(messages, tries=4):
    for attempt in range(tries):
        try:
            return client.chat.completions.create(model=MODEL, messages=messages)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

Ollama cục bộ không giới hạn tốc độ bạn, nhưng nó xếp hàng các yêu cầu khi mô hình bận, vì vậy trình bao bọc giống nhau không gây hại ở đó.

Cục bộ hay lưu trữ: cách quyết định

Không có lựa chọn nào tốt hơn nói chung. Sử dụng các điểm bên dưới làm danh sách kiểm tra.

  • Chọn Ollama cục bộ nếu bạn cần làm việc ngoại tuyến, nếu dữ liệu không bao giờ rời khỏi máy, nếu bạn đã sở hữu GPU đủ mạnh, hoặc nếu bạn muốn thử nhiều mô hình trọng số mở khác nhau một cách nhanh chóng.
  • Chọn API được lưu trữ nếu bạn không có GPU, nếu bạn chạy trên VPS nhỏ hoặc trong CI, nếu nhiều người hoặc dịch vụ chia sẻ một máy chủ phía sau, hoặc nếu bạn muốn cửa sổ ngữ cảnh dài mà không phải tự kích thước bộ nhớ. Mô hình được lưu trữ chấp nhận lên đến 100.000 token của prompt cộng với phần hoàn thành.
  • Kết hợp cả hai trong quá trình phát triển: lặp lại cục bộ, sau đó trỏ sản xuất vào URL được lưu trữ thông qua các biến môi trường.

Sử dụng API được lưu trữ được tính phí theo token, với giá $0,15 cho mỗi 1M token đầu vào và $0,50 cho mỗi 1M token đầu ra, từ tín dụng trả trước. trang giá cả liệt kê các số tiền nạp tiền, và các tài khoản mới có thể nhận $0,50 dùng thử chỉ với một cú nhấp chuột, không cần thẻ. Các prompt không được sử dụng để huấn luyện.

Lỗi bạn sẽ gặp

Triệu chứngNguyên nhân có thểCách khắc phục
Kết nối bị từ chối trên cổng 11434Máy chủ Ollama không chạyKhởi chạy ứng dụng hoặc chạy ollama serve
Không tìm thấy mô hìnhMô hình chưa bao giờ được kéo, hoặc tên có lỗi chính tảChạy ollama list, sau đó ollama pull tên bạn sử dụng
Gọi đầu tiên bị quá thời gian chờMô hình vẫn đang tảiTăng thời gian chờ hoặc gửi một yêu cầu làm nóng
Lỗi xác thực trên API được lưu trữThiếu hoặc sai khóa BearerHãy kiểm tra LLM_API_KEY và base URL
HTTP 429 với mã concurrencyHơn 8 yêu cầu đang thực hiện (2 trên khóa dùng thử)Giảm số lượng worker
HTTP 429 với mã rate_limitedVượt quá giới hạn yêu cầu mỗi phútGiảm tần suất và thử lại

Các yêu cầu bị lỗi hoặc bị từ chối ở phía máy chủ được lưu trữ sẽ không bị tính phí, vì vậy logic thử lại sẽ không làm bạn mất tiền cho các lần thử thất bại.

Hỏi đáp

Địa chỉ mặc định của Ollama API là gì?

Máy chủ Ollama cục bộ lắng nghe trên http://localhost:11434. Các endpoint gốc nằm dưới /api, chẳng hạn như /api/chat, và endpoint theo phong cách OpenAI nằm dưới /v1.

Tôi có thể sử dụng Python SDK của OpenAI với Ollama không?

Có. Hãy đặt base_url thành http://localhost:11434/v1 và truyền bất kỳ chuỗi nào làm khóa API. SDK sau đó sẽ gửi các yêu cầu hoàn thành trò chuyện tiêu chuẩn đến mô hình cục bộ của bạn.

Làm thế nào để chuyển từ Ollama sang API được lưu trữ?

Thay đổi base URL, khóa và tên mô hình. Nếu mã của bạn đọc các giá trị này từ biến môi trường, bạn sẽ không cần thay đổi mã.

API được lưu trữ có hoạt động mà không cần GPU ở phía tôi không?

Có. Mô hình chạy tại nhà cung cấp, vì vậy tập lệnh của bạn chỉ cần kết nối internet và khóa Bearer. Bạn trả tiền theo token từ tín dụng trả trước.

Khóa của bạn chỉ cách một bước

Tạo tài khoản, sao chép khóa, thay đổi URL cơ sở. Đó là toàn bộ thiết lập.

Lấy khóa API