T-CREATOR

WebLLM を 5 分で動かす:CDN 配信・モデル配置・WebGPU 有効化の最短ルート

WebLLM を 5 分で動かす:CDN 配信・モデル配置・WebGPU 有効化の最短ルート

ブラウザ上で AI モデルを動かせる WebLLM を、今すぐ試してみませんか? サーバー不要でプライバシーも守られる、そんな魅力的な技術が実は 5 分で動かせます。本記事では、CDN 経由での即座のセットアップから WebGPU の有効化まで、最短ルートでご紹介いたします。

背景

ブラウザ上で動く AI の時代

従来の AI モデル推論は、強力なサーバー側のリソースに依存していました。 しかし WebGPU という新しい Web 標準の登場により、ブラウザ上で GPU アクセラレーションを活用できる環境が整ってきました。 WebLLM は、この WebGPU を活用してブラウザ内で大規模言語モデル(LLM)を実行する画期的なライブラリです。

以下の図は、WebLLM がどのように動作するかを示しています。

mermaidflowchart TB
    browser["ブラウザ<br/>(Chrome/Edge/Safari)"]
    webgpu["WebGPU API"]
    gpu["GPU<br/>(ハードウェアアクセラレーション)"]
    webllm["WebLLM エンジン"]
    model["LLM モデル<br/>(Llama 3.1など)"]

    browser --> webllm
    webllm --> webgpu
    webgpu --> gpu
    webllm --> model

    style webllm fill:#e1f5ff
    style webgpu fill:#fff3e0
    style gpu fill:#f3e5f5

図で理解できる要点

  • WebLLM はブラウザ内で完結し、WebGPU を介して GPU を活用します
  • モデルはブラウザにダウンロードされ、ローカルで推論が実行されます
  • サーバーとの通信は不要で、プライバシーが保護されます

WebLLM の 3 つの魅力

この技術がもたらすメリットを見てみましょう。

#項目説明
1プライバシー保護データがサーバーに送信されず、すべてローカルで処理される
2レスポンスの高速化ネットワーク遅延がなく、モデルダウンロード後は即座に応答
3サーバーコスト削減推論処理がクライアント側で行われるため、サーバー負荷が軽減

課題

セットアップの複雑さという壁

WebLLM を試してみたい開発者が直面する課題は、主に以下の 3 点です。

モデル配置の手間

LLM モデルは数 GB のサイズがあり、どこからダウンロードして、どう配置すればよいのか悩む方も多いでしょう。 適切なモデルを選び、正しいパスを設定する必要があります。

WebGPU の有効化設定

ブラウザによっては WebGPU がデフォルトで有効化されていません。 特に Linux 環境では、フラグを立てる必要があり、初心者には敷居が高くなっています。

インストール方法の選択

npm、yarn などのパッケージマネージャーを使う方法と、CDN 経由で使う方法があります。 プロジェクトの性質に応じて最適な方法を選ぶ必要がありますが、情報が散在していて判断しづらい状況です。

以下の図は、セットアップ時に考慮すべきポイントを示しています。

mermaidflowchart TD
    start["WebLLM セットアップ開始"]

    start --> choice1{"開発環境は?"}
    choice1 -->|クイック検証| cdn["CDN 経由"]
    choice1 -->|本格開発| npm["npm/yarn"]

    cdn --> check_browser["ブラウザ確認"]
    npm --> install["パッケージインストール"]

    install --> check_browser
    check_browser --> webgpu_check{"WebGPU 対応?"}

    webgpu_check -->|はい| model_select["モデル選択"]
    webgpu_check -->|いいえ| enable["WebGPU 有効化"]

    enable --> model_select
    model_select --> ready["セットアップ完了"]

    style cdn fill:#e8f5e9
    style npm fill:#e3f2fd
    style enable fill:#fff3e0
    style ready fill:#f3e5f5

図で理解できる要点

  • 開発の目的によって CDN とパッケージマネージャーを使い分けます
  • WebGPU の対応確認は必須のステップです
  • 手順は明確ですが、各ステップで適切な選択が必要です

解決策

最速セットアップの 3 ステップ

本記事では、最も簡単な CDN 経由のアプローチを中心に解説します。 この方法なら、ビルドプロセスなしに即座に WebLLM を試せるでしょう。

ステップ 1:WebGPU 対応の確認と有効化

まず、お使いのブラウザが WebGPU に対応しているか確認しましょう。

対応状況の確認方法

以下のサイトにアクセスして、WebGPU の対応状況を確認できます。

texthttps://webgpureport.org/

このサイトで「WebGPU is supported」と表示されれば準備完了です。

ブラウザ別の対応状況(2025 年版)

各ブラウザの WebGPU 対応状況を確認してみましょう。

#ブラウザOS対応状況必要な操作
1Chrome 113 以降Windows/Mac/ChromeOS★★★ 完全対応なし
2Edge 113 以降Windows/Mac/ChromeOS★★★ 完全対応なし
3ChromeLinux★★☆ 部分対応フラグ有効化が必要
4Firefoxすべて★☆☆ Nightly のみNightly ビルドの利用
5SafarimacOS/iOS 18+★★☆ Technology PreviewFeature Flags 有効化

Linux で Chrome の WebGPU を有効化する

Linux 環境では、以下の手順でフラグを有効化します。

Chrome のアドレスバーに以下を入力してください。

textchrome://flags/#enable-unsafe-webgpu

表示される設定項目を「Enabled」に変更し、ブラウザを再起動しましょう。 これで WebGPU が利用可能になります。

ステップ 2:CDN 経由での WebLLM の読み込み

パッケージマネージャーを使わず、CDN から直接読み込む方法をご紹介します。

ESM 形式での読み込み

最もシンプルな方法は、ESM(ES Modules)形式でのインポートです。

javascript// WebLLM を CDN から直接インポート
const webllm = await import(
  'https://esm.run/@mlc-ai/web-llm'
);

この 1 行だけで、WebLLM のすべての機能にアクセスできます。 JSFiddle、Codepen、Scribbler などのオンライン環境でも即座に動作するでしょう。

jsdelivr CDN を使った読み込み

安定性を重視する場合は、jsdelivr CDN を利用することもできます。

javascript// jsdelivr CDN から最新版を読み込み
const webllm = await import(
  'https://cdn.jsdelivr.net/npm/@mlc-ai/web-llm@latest'
);

@latest の部分を特定のバージョン番号に変更すれば、バージョンを固定することも可能です。

ステップ 3:モデルのロードとエンジンの初期化

WebLLM を読み込んだら、次は AI モデルをロードしてエンジンを初期化します。

基本的なエンジン作成

CreateMLCEngine 関数を使って、エンジンを作成しましょう。

javascript// CreateMLCEngine 関数をインポート
import { CreateMLCEngine } from '@mlc-ai/web-llm';

CDN 経由で読み込んだ場合は、以下のようにアクセスします。

javascript// CDN 経由の場合
const { CreateMLCEngine } = webllm;

モデルの選択とロード

利用可能なモデルから、用途に合ったものを選びます。

javascript// Llama 3.1 8B モデルをロード(量子化版)
const engine = await CreateMLCEngine(
  'Llama-3.1-8B-Instruct-q4f32_1-MLC'
);

このコードは非同期で実行され、モデルのダウンロードと初期化が自動的に行われます。 初回は数 GB のダウンロードが発生するため、時間がかかる点にご注意ください。

プログレス表示の追加

ユーザーエクスペリエンスを向上させるため、ロード進捗を表示してみましょう。

javascript// 初期化の進捗をコンソールに表示
const engine = await CreateMLCEngine(
  'Llama-3.1-8B-Instruct-q4f32_1-MLC',
  {
    initProgressCallback: (progress) => {
      // progress オブジェクトには進捗情報が含まれる
      console.log(progress);
    },
  }
);

initProgressCallback は、ダウンロードの進行状況をリアルタイムで受け取るコールバック関数です。 これを使えば、プログレスバーなどの UI を実装できるでしょう。

プログレス情報の活用例

コールバックで受け取る情報を、より詳細に扱ってみます。

javascript// プログレス情報を詳細に表示
const engine = await CreateMLCEngine(
  'Llama-3.1-8B-Instruct-q4f32_1-MLC',
  {
    initProgressCallback: (progress) => {
      // 進捗率の表示
      if (progress.progress !== undefined) {
        console.log(
          `ロード中: ${(progress.progress * 100).toFixed(
            1
          )}%`
        );
      }

      // 現在の処理内容を表示
      if (progress.text) {
        console.log(`状態: ${progress.text}`);
      }
    },
  }
);

console.log('エンジンの初期化が完了しました!');

この実装により、ユーザーは何が起きているかを把握でき、待ち時間のストレスが軽減されます。

具体例

完全な動作サンプル

実際に動作する完全なコードを見てみましょう。 以下は HTML ファイル 1 つで動作する最小構成のサンプルです。

HTML ファイルの準備

まず、基本的な HTML 構造を作成します。

html<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>WebLLM 5分セットアップ</title>
  </head>
  <body>
    <h1>WebLLM チャットデモ</h1>

    <!-- プログレス表示エリア -->
    <div id="status">初期化前</div>

    <!-- 入力エリア -->
    <input
      type="text"
      id="input"
      placeholder="質問を入力"
      disabled
    />
    <button id="send" disabled>送信</button>

    <!-- 応答表示エリア -->
    <div id="output"></div>
  </body>
</html>

このシンプルな構造に、WebLLM を組み込んでいきます。

JavaScript の実装(初期化部分)

次に、WebLLM の初期化ロジックを追加しましょう。

html<script type="module">
  // WebLLM を CDN からインポート
  const { CreateMLCEngine } = await import(
    'https://esm.run/@mlc-ai/web-llm'
  );

  // DOM 要素の取得
  const statusDiv = document.getElementById('status');
  const inputField = document.getElementById('input');
  const sendButton = document.getElementById('send');
  const outputDiv = document.getElementById('output');
</script>

まず必要な要素を取得し、後の処理で使えるようにしています。

エンジンの初期化処理

続いて、エンジンを初期化するコードを追加します。

html<script type="module">
  // ... 前述のコード ...

  // エンジンの初期化(グローバル変数として保持)
  let engine;

  async function initEngine() {
    statusDiv.textContent = 'モデルをロード中...';

    try {
      // Llama 3.1 8B モデルで初期化
      engine = await CreateMLCEngine(
        'Llama-3.1-8B-Instruct-q4f32_1-MLC',
        {
          initProgressCallback: (progress) => {
            // 進捗率を表示
            const percent = (
              progress.progress * 100
            ).toFixed(1);
            statusDiv.textContent = `ロード中: ${percent}% - ${
              progress.text || ''
            }`;
          },
        }
      );

      // 初期化完了後の処理
      statusDiv.textContent =
        '準備完了!質問を入力してください';
      inputField.disabled = false;
      sendButton.disabled = false;
    } catch (error) {
      // エラーハンドリング
      statusDiv.textContent = `エラー: ${error.message}`;
      console.error('初期化エラー:', error);
    }
  }

  // ページ読み込み時に初期化を開始
  initEngine();
</script>

このコードは、ページを開いた瞬間からモデルのロードを開始します。 エラーが発生した場合も適切にハンドリングされるでしょう。

チャット機能の実装

最後に、実際に AI とチャットできる機能を実装します。

html<script type="module">
  // ... 前述のコード ...

  // メッセージ送信処理
  async function sendMessage() {
    const userInput = inputField.value.trim();

    // 空の入力はスキップ
    if (!userInput) return;

    // 入力欄をクリア
    inputField.value = '';

    // ユーザーのメッセージを表示
    outputDiv.innerHTML += `<p><strong>あなた:</strong> ${userInput}</p>`;

    // 応答を生成中のメッセージ
    statusDiv.textContent = '応答を生成中...';

    try {
      // AI に質問を送信
      const response = await engine.chat.completions.create(
        {
          messages: [{ role: 'user', content: userInput }],
        }
      );

      // AI の応答を取得
      const aiMessage = response.choices[0].message.content;

      // 応答を表示
      outputDiv.innerHTML += `<p><strong>AI:</strong> ${aiMessage}</p>`;
      statusDiv.textContent =
        '準備完了!質問を入力してください';
    } catch (error) {
      // エラーメッセージを表示
      outputDiv.innerHTML += `<p style="color: red;"><strong>エラー:</strong> ${error.message}</p>`;
      statusDiv.textContent = 'エラーが発生しました';
      console.error('チャットエラー:', error);
    }
  }

  // ボタンクリック時のイベント
  sendButton.addEventListener('click', sendMessage);

  // Enter キー押下時のイベント
  inputField.addEventListener('keypress', (e) => {
    if (e.key === 'Enter') {
      sendMessage();
    }
  });
</script>

これで、ブラウザ上で動作する完全な AI チャットアプリケーションが完成しました。 サーバー不要で、すべての処理がローカルで実行されます。

動作フロー図

実装したアプリケーションの動作フローを図で確認しましょう。

mermaidsequenceDiagram
    participant User as ユーザー
    participant Browser as ブラウザ
    participant WebLLM as WebLLM エンジン
    participant Model as LLM モデル

    User->>Browser: ページを開く
    Browser->>WebLLM: エンジン初期化開始
    WebLLM->>Model: モデルをダウンロード
    Model-->>WebLLM: ダウンロード完了
    WebLLM-->>Browser: 初期化完了
    Browser-->>User: 入力可能状態

    User->>Browser: メッセージ入力・送信
    Browser->>WebLLM: chat.completions.create()
    WebLLM->>Model: 推論実行(ローカル)
    Model-->>WebLLM: 応答生成
    WebLLM-->>Browser: 応答テキスト
    Browser-->>User: AI の応答を表示

図で理解できる要点

  • すべての処理がブラウザ内で完結しています
  • モデルは一度ダウンロードされれば、キャッシュされます
  • 推論はローカルで実行され、サーバーへの通信は発生しません

パッケージマネージャーを使った本格的なセットアップ

プロダクション環境では、パッケージマネージャーを使った方が管理しやすいでしょう。

Yarn でのインストール

プロジェクトに WebLLM を追加します。

bash# Yarn を使ってインストール
yarn add @mlc-ai/web-llm

このコマンドで、最新の WebLLM パッケージがプロジェクトに追加されます。

TypeScript での型安全な実装

型定義を活用して、より堅牢なコードを書いてみましょう。

typescript// 必要な型と関数をインポート
import {
  CreateMLCEngine,
  MLCEngine,
  InitProgressReport,
} from '@mlc-ai/web-llm';

型をインポートすることで、IDE の補完機能が利用でき、開発効率が向上します。

エンジンの型安全な初期化

TypeScript の型システムを活用した実装例です。

typescript// エンジンの型を明示的に宣言
let engine: MLCEngine;

// 初期化関数(型安全)
async function initEngine(): Promise<void> {
  try {
    engine = await CreateMLCEngine(
      'Llama-3.1-8B-Instruct-q4f32_1-MLC',
      {
        initProgressCallback: (
          progress: InitProgressReport
        ) => {
          // 型情報があるため、progress のプロパティが補完される
          console.log(
            `進捗: ${progress.progress}`,
            progress.text
          );
        },
      }
    );

    console.log('エンジンの準備が完了しました');
  } catch (error) {
    // エラー型のガード
    if (error instanceof Error) {
      console.error(`初期化エラー: ${error.message}`);
    }
    throw error;
  }
}

型情報により、コンパイル時にエラーを検出でき、バグを未然に防げるでしょう。

利用可能なモデル一覧

WebLLM では、様々な LLM モデルが利用可能です。 用途に応じて最適なモデルを選びましょう。

主要な対応モデル

以下の表に、代表的なモデルをまとめました。

#モデル名パラメータ数推奨用途メモリ使用量目安
1Llama-3.1-8B-Instruct8B汎用チャット約 5GB
2Llama-3-8B-Instruct8B汎用チャット約 5GB
3Llama-2-7B-Chat7B軽量チャット約 4GB
4Phi-3-mini3.8B高速応答約 2.5GB
5Phi-22.7B軽量タスク約 2GB
6Gemma-2B-Instruct2B組み込み向け約 1.5GB
7Qwen-0.5B-Instruct0.5B超軽量約 500MB
8Mistral-7B-Instruct7B高性能汎用約 4.5GB

モデル選択のポイント

用途に応じたモデル選択の指針をご紹介します。

javascript// クイックプロトタイプには軽量モデル
const quickEngine = await CreateMLCEngine(
  'Phi-3-mini-4k-instruct-q4f16_1-MLC'
);

軽量モデルは起動が早く、開発段階での試行錯誤に向いています。

javascript// 本格的なアプリケーションには高性能モデル
const productionEngine = await CreateMLCEngine(
  'Llama-3.1-8B-Instruct-q4f32_1-MLC'
);

高性能モデルは応答品質が高く、ユーザー向けサービスに適しているでしょう。

最新モデルの確認方法

WebLLM が対応する最新のモデル一覧は、公式サイトで確認できます。

texthttps://mlc.ai/models

このページでは、各モデルの詳細なスペックや、推奨される使用ケースも紹介されています。

まとめ

5 分で実現できたこと

本記事では、WebLLM を最短ルートでセットアップする方法をご紹介しました。 CDN 経由の読み込みを使えば、わずか数行のコードでブラウザ上で AI が動作します。

重要なポイントをおさらいしましょう。

#ポイント内容
1WebGPU の確認webgpureport.org で対応状況を確認する
2CDN の活用esm.run または jsdelivr から直接インポート可能
3モデルの選択用途に応じて 0.5B〜8B のモデルから選ぶ
4初期化の監視initProgressCallback でユーザー体験を向上
5型安全性TypeScript を使えばより堅牢な実装が可能

次のステップ

基本的なセットアップができたら、以下の発展的なトピックにも挑戦してみてください。

  • ストリーミング応答の実装で、よりインタラクティブな体験を提供する
  • カスタムモデルの読み込みで、特定用途に最適化する
  • Service Worker との組み合わせで、オフライン動作を実現する
  • React や Vue などのフレームワークとの統合で、本格的な UI を構築する

WebLLM は、ブラウザ AI の可能性を大きく広げる技術です。 プライバシーを守りながら、高速で応答する AI アプリケーションを、ぜひあなたの手で作ってみてください。

関連リンク