Cloudflare Workers AIでエッジ推論を実践する:Llama 3をサーバーレスで動かすサーバーレスAIの最前線

はじめに

「自社のアプリケーションに最新のLLM(大規模言語モデル)を組み込みたいが、高価なGPUサーバーの運用コストや複雑なインフラ管理が壁になっている…」 「AIチャットボットを作ったはいいものの、APIのレスポンスが遅くてユーザー体験が悪い…」 「そもそも、AI推論環境をどう構築すればいいのか、最初の一歩が踏み出せない…」

多くのエンジニアが、AI、特にLLMをプロダクトに導入する際に、このような課題に直面しているのではないでしょうか。AIの力は魅力的ですが、その裏にはコスト、パフォーマンス、そして運用の複雑さという大きなハードルが存在します。

もし、これらの課題を解決し、サーバーの管理を一切行わずに、世界中のユーザーから最も近い場所で、低遅延かつ低コストでLlama 3のような高性能LLMを動かせるとしたらどうでしょう?

この記事では、それを実現するCloudflareの画期的なサービス「Workers AI」について、その核心から実践的な使い方までを徹底的に解説します。この記事を読み終える頃には、あなたはWorkers AIの基本をマスターし、実際にLlama 3をエッジで動かすサーバーレスAIアプリケーションを自分の手で構築できるようになっているはずです。さあ、サーバーレスAIの最前線へ、一緒に飛び込んでいきましょう。

なぜ今、エッジでのAI推論が重要なのか?

ChatGPTの登場以来、LLMは技術の世界に革命をもたらしました。しかし、その強力な能力を広くアプリケーションに組み込むには、いくつかの根深い課題が存在します。

従来のAI推論が抱える課題

  1. 高コスト: 高性能なAIモデル、特にLLMの推論には、強力なGPUが必要です。これらのGPUサーバーを購入またはレンタルするには莫大な費用がかかり、特にスモールスタートしたいプロジェクトにとっては大きな障壁となります。
  2. 高レイテンシ: 従来のAI推論は、特定のリージョンに存在する大規模なデータセンターで実行されるのが一般的でした。ユーザーがデータセンターから物理的に遠い場所にいる場合、ネットワークの往復時間(RTT)がボトルネックとなり、応答が遅れてしまいます。リアルタイム性が求められるチャットボットやインタラクティブなアプリケーションでは、この遅延は致命的です。
  3. 複雑なインフラ管理: GPUサーバーのプロビジョニング、OSやライブラリのバージョン管理、セキュリティパッチの適用、そしてトラフィックに応じたスケーリング… AIモデルを安定して稼働させるためには、専門的な知識を持つインフラエンジニアによる24時間365日の運用が不可欠でした。
  4. スケーラビリティの難しさ: バイラルヒットしたサービスのように、アクセスが急増した際、迅速にインフラをスケールさせるのは容易ではありません。需要を予測して事前にサーバーを準備しておく必要があり、コストの最適化も困難でした。

これらの課題は、多くの開発者がAI活用のアイデアを形にするのをためらわせる原因となっていました。

解決策としての「サーバーレスAI」と「エッジコンピューティング」

こうした状況を打破するために登場したのが、「サーバーレスAI」という新しいパラダイムです。これは、Cloudflare Workers AIが提唱するコンセプトで、その名の通り、開発者がサーバーインフラを一切意識することなくAIモデルを利用できる仕組みです。

この中核をなすのがエッジコンピューティングです。

1
2
3
4
5
6
7
【従来の集中型モデル】
  [ユーザー] <---- (高いレイテンシ) ----> [中央データセンター (GPUサーバー)]

【エッジコンピューティングモデル】
  [ユーザー] <--> (低いレイテンシ) <--> [最寄りのCloudflareエッジ拠点]
                                             |
                                        [Workers AIで推論実行]

エッジコンピューティングは、計算処理をユーザーの物理的な位置の近く(=エッジ)で行う技術です。Cloudflareは世界120カ国以上、300都市以上に広がる広大なグローバルネットワークを持っており、Workers AIはこのネットワーク上の無数のサーバーでAIモデルの推論を実行します。

これにより、ユーザーからのリクエストは最も近いエッジ拠点で処理されるため、物理的な距離に起因するレイテンシを劇的に削減できます。さらに、インフラはCloudflareが完全に管理してくれるため、開発者はコードを書くことだけに集中できます。コストも実際に推論を実行した分だけの従量課金制であり、スケーラビリティもCloudflareのネットワークが自動で担保してくれます。

Cloudflare Workers AIは、まさに従来のAI推論が抱えていたコスト、レイテンシ、運用の課題をまとめて解決する、ゲームチェンジャー的な存在なのです。

Workers AIでLlama 3を動かす!ハンズオンチュートリアル

それでは、実際にCloudflare Workers AIを使って、Meta社が開発した最新のオープンソースLLM「Llama 3」を動かすアプリケーションを構築していきましょう。驚くほど簡単であることに、きっと驚かれるはずです。

ステップ1: 環境構築

まず、開発に必要なツールをセットアップします。必要なのはNode.jsと、Cloudflare Workersを管理するためのCLIツール wrangler です。

  1. Node.jsとnpmのインストール: もしまだインストールしていなければ、公式サイトからご自身の環境に合ったものをインストールしてください。

  2. Wrangler CLIのインストール: ターミナルを開き、以下のコマンドを実行して wrangler をグローバルにインストールします。

    1
    
    npm install -g wrangler
    
  3. Cloudflareアカウントへのログイン: wrangler があなたのCloudflareアカウントを操作できるように、認証を行います。以下のコマンドを実行するとブラウザが開き、ログインを求められます。

    1
    
    wrangler login
    

    ログインが成功すれば、準備は完了です。

ステップ2: Workersプロジェクトの作成

次に、wrangler を使ってWorkers AI用のプロジェクトテンプレートから新しいプロジェクトを作成します。

1
npm create cloudflare@latest my-llama-worker -- --template=worker-ai

my-llama-worker という名前のディレクトリが作成され、中にいくつかのファイルが生成されます。主なファイルは以下の通りです。

  • wrangler.toml: プロジェクトの設定ファイル。Workerの名前やAIモデルのバインディングなどを定義します。
  • src/index.ts: Workerの本体となるTypeScriptのソースコードです。ここにロジックを記述します。

ステップ3: AIバインディングの設定

WorkerからWorkers AIの機能を利用するには、wrangler.toml ファイルで「AIバインディング」を設定する必要があります。これにより、コード内から AI という名前でWorkers AIの機能にアクセスできるようになります。

wrangler.toml を開き、以下の内容を追加または確認してください。

1
2
3
4
5
6
7
8
9
# wrangler.toml

name = "my-llama-worker"
main = "src/index.ts"
compatibility_date = "2024-04-05"

# Workers AIへのアクセスを有効にするためのバインディング
[[ai]]
binding = "AI"

この [[ai]] ブロックが、env.AI という形でコードからAI機能を使えるようにするための魔法の呪文です。

ステップ4: Llama 3を呼び出すコードの実装

いよいよ核心部分である、Llama 3を呼び出すコードを書いていきましょう。src/index.ts を開き、以下のように編集します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// src/index.ts

// 環境変数(AIバインディングを含む)の型定義
export interface Env {
  AI: Ai;
}

export default {
  // fetchイベントハンドラ:Workerがリクエストを受け取ったときに実行される
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // URLのクエリパラメータから 'prompt' を取得
    const { searchParams } = new URL(request.url);
    const prompt = searchParams.get('prompt');

    // プロンプトが指定されていない場合はエラーメッセージを返す
    if (!prompt) {
      return new Response('Error: "prompt" query parameter is required.', { status: 400 });
    }

    // env.AI.run() を使ってLlama 3モデルを呼び出す
    // 第1引数: 実行したいモデルのID
    // 第2引数: モデルへの入力データ
    const response = await env.AI.run(
      '@cf/meta/llama-3-8b-instruct',
      {
        prompt: prompt,
      }
    );

    // AIからの応答をJSON形式でクライアントに返す
    return new Response(JSON.stringify(response), {
      headers: { 'Content-Type': 'application/json' },
    });
  },
};

コードのポイントを解説します。

  • export interface Env: wrangler.toml で設定した AI バインディングをTypeScriptの型システムに認識させるための定義です。
  • async fetch(request: Request, env: Env, ...): これがWorkerのエントリーポイントです。env オブジェクトを通じて AI バインディングにアクセスできます。
  • const prompt = searchParams.get('prompt'): URLのクエリパラメータ(例: ?prompt=こんにちは)からプロンプト文字列を取得しています。
  • await env.AI.run(...): ここがWorkers AIを呼び出している部分です。
    • '@cf/meta/llama-3-8b-instruct': Cloudflareが提供するLlama 3 8B InstructモデルのIDです。他にも様々なモデルが利用可能です。
    • { prompt: prompt }: モデルへの入力です。最もシンプルな形式でプロンプトを渡しています。
  • new Response(...): モデルからの推論結果(response)をJSON形式に変換して、HTTPレスポンスとして返却しています。

たったこれだけのコードで、Llama 3を呼び出すAPIが完成しました。

ステップ5: ローカルでのテスト

デプロイする前に、ローカル環境で動作を確認しましょう。ターミナルで以下のコマンドを実行します。

1
wrangler dev

これにより、ローカル開発サーバーが起動します。http://localhost:8787 でリクエストを受け付ける状態になります。

別のターミナルを開き、curl コマンドを使ってAPIを叩いてみましょう。

1
2
# プロンプトをURLエンコードして渡す
curl "http://localhost:8787/?prompt=Cloudflare%20Workers%20AI%E3%81%AE%E9%AD%85%E5%8A%9B%E3%82%923%E3%81%A4%E6%95%99%E3%81%88%E3%81%A6"

しばらく待つと、以下のようなJSON形式のレスポンスが返ってくるはずです。(内容は実行ごとに異なります)

1
2
3
{
  "response": "もちろんです!Cloudflare Workers AIの魅力を3つご紹介します。\n\n1.  **超低レイテンシ**: 世界中に分散したCloudflareのエッジネットワーク上で推論が実行されるため、ユーザーに最も近い場所で処理が行われます。これにより、従来のクラウドAIサービスと比較して劇的に高速な応答が可能です。\n\n2.  **サーバーレスで簡単**: 開発者はインフラの管理やスケーリングについて一切心配する必要がありません。Wrangler CLIを使って数コマンドでデプロイでき、コードを書くことに集中できます。\n\n3.  **驚異的なコストパフォーマンス**: GPUサーバーを常時稼働させる必要がなく、実際に推論を実行した分だけの従量課金制です。 generousな無料枠も用意されており、個人開発やプロトタイピングにも最適です。"
}

見事にLlama 3がローカル環境で動作しました!

ステップ6: Cloudflareへデプロイ

最後に、作成したWorkerをCloudflareのグローバルネットワークにデプロイします。コマンドはたった一つです。

1
wrangler deploy

コマンドが成功すると、あなたのWorkerに割り当てられた公開URL(例: https://my-llama-worker.YOUR_SUBDOMAIN.workers.dev)が表示されます。

今度はこの公開URLに対して、先ほどと同じようにcurlでリクエストを送ってみましょう。

1
curl "https://my-llama-worker.YOUR_SUBDOMAIN.workers.dev/?prompt=Cloudflare%20Workers%20AI%E3%81%AE%E9%AD%85%E5%8A%9B%E3%82%923%E3%81%A4%E6%95%99%E3%81%88%E3%81%A6"

世界中のどこからアクセスしても、あなたの現在地から最も近いエッジ拠点でLlama 3が実行され、驚くほど高速に応答が返ってくることを体感できるはずです。

メリットとデメリット、そして他ツールとの比較

Workers AIは非常に強力ですが、万能ではありません。その特性を理解し、他の選択肢と比較することで、最適な技術選定が可能になります。

Workers AIのメリット

  • 圧倒的な低レイテンシ: ユーザーの近くで実行されるため、物理的な遅延が最小限に抑えられます。
  • 驚異的な低コスト: 従量課金制で、無料枠も充実しています。高価なGPUサーバーを維持する必要がありません。
  • 究極のシンプルさ: サーバーレスなのでインフラ管理は不要。wrangler deploy だけでグローバルに展開できます。
  • 自動スケーリング: Cloudflareの巨大なネットワークが、アクセスの増減に合わせて自動でスケールしてくれます。
  • 豊富なモデルラインナップ: テキスト生成(Llama 3, Gemma, Mistralなど)、画像生成(Stable Diffusion)、埋め込み、音声認識など、多様なタスクに対応したモデルがプリセットされています。

Workers AIのデメリットと注意点

  • モデルの制約: Cloudflareが提供する最適化されたモデルしか利用できません。自前で学習させたカスタムモデルを持ち込むことは(現時点では)できません。
  • 限定的なカスタマイズ: モデルのFine-tuning(微調整)のような高度なカスタマイズはサポートされていません。
  • プラットフォームの実行制限: Workersプラットフォーム自体の実行時間やメモリの制限を受けます。非常に長時間の推論や大規模なデータ処理には向かない場合があります。
  • ベンダーロックイン: Cloudflareのエコシステムに依存する形になるため、将来的に他のプラットフォームへ移行する際の障壁になる可能性があります。

他のAI推論プラットフォームとの比較

特徴 Cloudflare Workers AI AWS SageMaker / Google Vertex AI Hugging Face Inference Endpoints
パラダイム サーバーレス, エッジ フルマネージド, 集中型クラウド マネージドインスタンス, 集中型クラウド
レイテンシ 非常に低い 高い(エッジ構成は複雑) 高い
コスト 非常に低い(従量課金) 高い(インスタンス時間課金) 比較的高い(インスタンス時間課金)
運用 非常に簡単 複雑(多くの設定項目) 比較的簡単
スケーリング 自動(非常に得意) 自動(設定が必要) 自動(設定が必要)
モデルの自由度 低い(提供モデルのみ) 非常に高い(カスタムモデル可) 非常に高い(HF Hubの全モデル)
Fine-tuning 不可 可能 可能
得意な用途 低レイテンシなAPI, チャットボット, プロトタイプ 研究開発, 高度なカスタムモデル, 大規模バッチ処理 豊富なモデルの活用, 研究開発

結論として、Workers AIは「ユーザー向けのインタラクティブなAI機能を、低コスト・低レイテンシで素早く提供したい」というユースケースにおいて、現時点で最強の選択肢の一つと言えるでしょう。 一方で、独自のモデルを動かしたい、あるいは複雑なFine-tuningが必要な場合は、AWS SageMakerやVertex AIのような、より自由度の高いプラットフォームを検討する必要があります。

現場で使える実践的なTips

基本的な使い方をマスターしたところで、さらに実践的なアプリケーションを構築するためのTipsをいくつかご紹介します。

1. ストリーミングでUXを向上させる

LLMの応答は生成に時間がかかるため、全てのテキストが生成されるのを待っているとユーザーは待たされてしまいます。これを解決するのがストリーミング応答です。生成されたトークンを逐次クライアントに送ることで、ユーザーはリアルタイムに応答が表示されるような体験を得られます。

src/index.ts を以下のように変更します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ... (Envインターフェースは同じ)

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const { searchParams } = new URL(request.url);
    const prompt = searchParams.get('prompt') || "What is streaming?";

    // env.AI.runのオプションに stream: true を追加
    const stream = await env.AI.run(
      '@cf/meta/llama-3-8b-instruct',
      {
        prompt: prompt,
        stream: true, // ストリーミングを有効化
      }
    );

    // レスポンスのContent-Typeを 'text/event-stream' に設定
    return new Response(stream, {
      headers: { 'Content-Type': 'text/event-stream' },
    });
  },
};

変更点は、env.AI.run のオプションに stream: true を追加し、レスポンスのContent-Typetext/event-streamに変更しただけです。これだけで、Workers AIはServer-Sent Events(SSE)形式で応答をストリーミングしてくれます。

2. 対話履歴を考慮したチャットボットを構築する

より自然な対話を実現するには、過去のやり取りをコンテキストとしてLLMに渡す必要があります。prompt の代わりに messages 配列を使用することで、これを簡単に実現できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// ...

const messages = [
  // システムプロンプトでAIの役割を定義
  { role: 'system', content: 'あなたは親切でユーモアのあるアシスタントです。' },
  // 過去のユーザーの発言
  { role: 'user', content: '一番面白いジョークを教えて。' },
  // 過去のAIの応答
  { role: 'assistant', content: 'なぜ自転車は倒れないのでしょうか?…それは、two-tired(疲れている/タイヤが2つ)だからです!' },
  // 今回のユーザーの発言
  { role: 'user', content: 'うーん、別のを教えて。' }
];

const response = await env.AI.run(
  '@cf/meta/llama-3-8b-instruct',
  {
    messages: messages, // promptの代わりにmessagesを使用
  }
);

// ...

実際のアプリケーションでは、このmessages配列をCloudflare D1(サーバーレスDB)やKV(キーバリューストア)に保存し、ユーザーごとに管理することで、連続した対話が可能な本格的なチャットボットを構築できます。

3. KVを使って高頻度のリクエストをキャッシュする

「今日の天気は?」のような頻繁に来る同じ質問に対して、毎回LLMを呼び出すのはコストと時間の無駄です。Cloudflare KVを使えば、一度生成した応答をキャッシュし、2回目以降はキャッシュから高速に返すことができます。

wrangler.toml にKVの設定を追加します。

1
2
3
4
# ...
[[kv_namespaces]]
binding = "AI_CACHE"
id = "YOUR_KV_NAMESPACE_ID" # wrangler kv:namespace create AI_CACHE で作成

そして、src/index.ts でキャッシュロジックを実装します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// ... (EnvにKVの型定義を追加)
export interface Env {
  AI: Ai;
  AI_CACHE: KVNamespace;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // ... (promptの取得)

    // KVからキャッシュを探す
    const cacheKey = `prompt:${prompt}`;
    const cachedResponse = await env.AI_CACHE.get(cacheKey, { type: 'json' });
    if (cachedResponse) {
      console.log("Cache HIT!");
      return new Response(JSON.stringify(cachedResponse), {
        headers: { 'Content-Type': 'application/json' },
      });
    }

    console.log("Cache MISS. Calling AI...");
    // キャッシュがなければAIを呼び出す
    const aiResponse = await env.AI.run(/* ... */);

    // 結果をKVに保存(有効期限60分)
    // ctx.waitUntil()でレスポンス返却後も非同期処理を継続させる
    ctx.waitUntil(env.AI_CACHE.put(cacheKey, JSON.stringify(aiResponse), { expirationTtl: 3600 }));

    return new Response(JSON.stringify(aiResponse), {
      headers: { 'Content-Type': 'application/json' },
    });
  },
};

この実装により、同じプロンプトに対しては60分間、AIを呼び出すことなくキャッシュから即座に応答を返すことができ、コスト削減とパフォーマンス向上を両立できます。

まとめ

本記事では、Cloudflare Workers AIという革新的なプラットフォームを用いて、最新のLLMであるLlama 3をエッジで実行する方法を、具体的なチュートリアルと実践的なTipsを交えて解説しました。

Workers AIの登場は、AIアプリケーション開発の常識を覆すものです。

かつては専門家チームと潤沢な予算がなければ手が出せなかったAI推論環境が、今や個人開発者でも wrangler deploy という一つのコマンドで、全世界に低遅延かつスケーラブルな形で展開できるようになりました。これは、AI活用の民主化における大きな一歩です。

もちろん、Workers AIにも制約はありますが、そのシンプルさ、パフォーマンス、そしてコスト効率は、特にユーザー向けのインタラクティブな機能開発において絶大な威力を発揮します。

今日学んだ知識を元に、ぜひあなた自身のアイデアを形にしてみてください。AIを使った要約機能、コンテンツ生成アシスタント、インテリジェントなチャットボット…可能性は無限大です。

サーバーレスAIの時代は、まだ始まったばかりです。Cloudflare Workers AIを使いこなし、次世代のアプリケーションを創造する旅に、今すぐ出発しましょう!