LiteLLM を使って色々な LLM API サービスをいい感じに使いこなす
この記事は Magic Moment Advent Calendar 2024 5 日目の記事です。
Magic Moment でプロダクトデータを活用した機能の開発・検討をしている @nagomiso です。
気づけば前回の記事から 1 年が経過していました。時間の流れが早すぎて驚きを隠せません。 ここ 1 年での変化としては体重が大幅に増えました。原因は間違いなくラーメンの食べ過ぎです。節制せねば… 🍜
はじめに
Google が Gemini 1.5 Pro / Flush を公開したり OpenAI が GPT-4o / 4o mini, OpenAI o1 / o1 mini を公開したりと 2024 年も LLM の進化には目を見張るものがありました。
こうした進化によって開発で使える高性能な LLM API サービスが増えるのは喜ばしいことですがサービス毎に API が異なっているのでサービスを比較検討しながら開発する際に辛さを感じることも少なくありません。この辛さを軽減してくれるのが LiteLLM です。
LiteLLM
LiteLLM は世の中に存在する様々な LLM API サービスの呼び出しをラップして OpenAI と同じ形式で透過的に利用できるようにしてくれる OSS です。
すでに LiteLLM の魅力を紹介する記事は存在していますが私からも改めて紹介させていただければと思います。
LiteLLM の魅力
簡単に利用サービスを切り替えられる
なんといっても LiteLLM の最大魅力は利用サービスを簡単に切り替えられることです。
OpenAI, VertexAI, Anthropic などが提供する LLM API を
- Python SDK
- Proxy Server
の 2 つの形式で共通的な API として利用できます。
Python SDK として利用する場合は以下のような形で
from litellm import completion
import os
messages = [
{"role": "system", "content": "おまえは虎になるのだ"},
{"role": "user", "content": "鳴き声を聞かせてください"},
]
# OpenAI
os.environ["OPENAI_API_KEY"] = "openai-api-key"
response = completion(
model="gpt-4o-mini-2024-07-18",
messages=messages,
)
# VertexAI
os.environ["VERTEX_PROJECT"] = "project"
os.environ["VERTEX_LOCATION"] = "asia-northeast1"
response = completion(
model="gemini-1.5-flash-001",
messages=messages,
)
# Anthropic
os.environ["ANTHROPIC_API_KEY"] = "your-api-key"
response = completion(
model="claude-3-5-haiku-20241022",
messages=messages
)
Proxy Server として利用する場合は以下のような形で
# OpenAI
❯ curl -X POST 'http://localhost:4000/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-virtual-key' \
-d '{
"model": "gpt-4o-mini-2024-07-18",
"messages": [
{"role": "system", "content": "おまえは虎になるのだ"},
{"role": "user", "content": "鳴き声を聞かせてください"}
]
}'
# VertexAI
❯ curl -X POST 'http://localhost:4000/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-virtual-key' \
-d '{
"model": "gemini-1.5-flash-001",
"messages": [
{"role": "system", "content": "おまえは虎になるのだ"},
{"role": "user", "content": "鳴き声を聞かせてください"}
]
}'
# Anthropic
❯ curl -X POST 'http://localhost:4000/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-virtual-key' \
-d '{
"model": "claude-3-5-haiku-20241022",
"messages": [
{"role": "system", "content": "おまえは虎になるのだ"},
{"role": "user", "content": "鳴き声を聞かせてください"}
]
}'
それぞれ利用できます。モデル名を変えるだけで済むので利用側としては非常に楽ですね。
Budget 制御, Rate Limit 制御ができる
ここは個人的な地味に嬉しいポイント。LiteLLM では指定した期間内における Budget 上限や Rate Limit の設定ができます。
こちらも Python SDK, Proxy Server どちらでも設定できます。
Proxy Server 上で利用する場合は
- User: 利用者個人
- Team: 利用者個人を束ねるチーム
という単位で制御の設定ができます。
LLM API サービスはモデルによってはコストが馬鹿にならないのでこうした制御の仕組みによって思わぬ使い過ぎが抑止できてお財布面で安心感が持てます[1]。
Magic Moment での活用
Magic Moment では
- 複数の LLM API サービスを簡単に切り替えて利用したい
- Budget 制御, Rate Limit 制御を設定して使い過ぎを防ぎたい
という点に加えて Python 以外の言語でも利用したいという要望があったため LLM API 利用基盤として LiteLLM Proxy Server を Cloud Run 上に Self Host して運用しています。
Self Host にあたっては以下のようなちょっとした工夫をしました。
-
インストールする依存関係を絞って軽量化したイメージを自前で作成して使用した
- 公式から提供されているイメージは簡単に利用できて便利なのですが社内の用途では利用しない依存関係も含まれていました。
- 依存関係の見直しや Multi Stage Build などを駆使して 1 GB 以上あったイメージサイズを 800 MB 以下に軽量化できました。
-
サービスの起動と Migration を明確に分けて実行するようにした
- LiteLLM Proxy Server はデフォルトだとサービス起動時 無邪気に
prisma db push --accept-data-loss
を実行する実装となっています。 - 都度 Schema 更新が走って起動の時間が延びてしまうことになるので昨今のコンテナがスケールに応じて増減するような実行環境では不都合があります。
- この問題を解消するためサービス起動に用いるマニフェストと Migration に用いるマニフェストを分けて定義しておりサービス起動時には Migration は実行せずにサービスを起動するようにしました。具体的には以下のような設定をしています[2]。
- サービス用のマニフェストは環境変数に
DISABLE_SCHEMA_UPDATE=true
を設定する - Migration 用のマニフェストは環境変数に
DISABLE_SCHEMA_UPDATE=false
を設定しcommand
に[python3, -m, litellm.proxy.prisma_migration]
を指定する - 使用するイメージはどちらも同じ
- サービス用のマニフェストは環境変数に
- LiteLLM Proxy Server はデフォルトだとサービス起動時 無邪気に
LiteLLM Proxy Server を導入したことで開発者は LLM API サービス固有の SDK を使った実装を考える必要がなくなり LLM API サービスを利用した機能開発そのものへ集中できるようになりました。
まとめ
LLM API サービスを透過的に利用できる LiteLLM の魅力と Magic Moment での活用事例について紹介しました。
今回紹介した内容以外にも LLM API サービス呼び出しのフォールバック機能や Langfuge, LangSmith といったトレーシング機能のような LLM API サービスを使う際の便利機能が LiteLLM には搭載されています。
"いい感じに LLM API サービスを使いたい" という方はぜひ LiteLLM を試してみてください。
さて次回のアドベントカレンダーは引き続き @nagomiso の「Prisma Migrate 小ネタ」 です。
「次回も nagomiso と地獄に付き合ってもらう(某有名次回予告風)」
-
ただちょっと残念だったのは制限を設定できる期間が 1 週間, 1 ヶ月のような単位でしか設定できなかったことです。「月末まで」「週末まで」といった形で設定できるとより実際の用途に即した制御ができて嬉しかったなと思いました。 ↩︎
-
この方法は自分で LiteLLM の実装と挙動を見て思いついたものなのですが後から公式のドキュメントにも同じようなプラクティス(ただし Helm を使った例)が記載されていることに気づきました。やはり公式のドキュメントを読むのは大事ですね 🫠 ↩︎
Discussion