実行プログラムと拡張機能
Transformers.jsでブラウザー内のローカルLLMを実行する
入力した質問にブラウザー内で答える小さなWebアプリを作ります。
Transformers.jsはJavaScriptからAIモデルを実行するライブラリです。ONNX形式のモデルを取得すれば、ブラウザーでも回答を生成できます。この記事では4.3.0の公式例にあるLFM2.5-350Mを使い、質問入力欄と回答ボタンを作ります。
ブラウザー内のローカル推論で何が変わる?
一般的なAIサイトは質問をサーバーに送り、回答を受け取ります。ブラウザー内のローカル推論では、その処理をユーザーのコンピューターが担います。Transformers.jsの`pipeline1()`を一度作り、入力文を渡すと、取得済みのモデルが同じページ内で回答を生成します。
別途Python推論サーバーを導入する必要がなく、小さなWeb機能の試作に向いています。テキスト分類や短い回答など、負荷の小さい作業から始めましょう。多数の同時利用者や大きなモデルの継続的な提供には、専用のサービングエンジンを検討します。

4.3.0で使うモデルと実行デバイスを選ぶ
Transformers.js 4.3.0は2026年9月16日に公開されました。リリース例は`onnx-community/LFM2.5-350M-ONNX`でWebGPU2用の`q4f16`を使います。このモデルリポジトリにはCPU/WASMで選べる`q4`ファイルもありますが、`q8`ファイルは確認できなかったため、以下のコードはデバイスに応じて2つの形式から選びます。
別のONNXモデルに切り替える場合は、選んだdtypeのファイルがそのリポジトリにあることを確認してください。モデルを読み込むにはファイルと推論設定の一致が必要です。
公式資料はこのモデルの最小システムRAM3・GPU4メモリを示していません。モデルファイルのサイズだけで実行可否を判断せず、初回実行時にブラウザーのタスクマネージャーでタブのメモリ使用量を確認してください。
| 実行経路 | 設定 | 使用条件 |
|---|---|---|
| CPU/WASM | `device`を省略し、`dtype: 'q4'`を指定 | このリポジトリにあるq4ファイルを使う標準の推論経路 |
| 対応GPU | `device: 'webgpu'`, `dtype: 'q4f16'` | WebGPU adapterを取得でき、この形式に対応している場合 |
| q8 | このモデルでは選ばない | モデルリポジトリにq8 ONNXファイルがなく、使用できません |
このモデルリポジトリで確認した実行形式とブラウザーデバイス経路です。
CPU/WASM
- 設定
- `device`を省略し、`dtype: 'q4'`を指定
- 使用条件
- このリポジトリにあるq4ファイルを使う標準の推論経路
対応GPU
- 設定
- `device: 'webgpu'`, `dtype: 'q4f16'`
- 使用条件
- WebGPU adapterを取得でき、この形式に対応している場合
q8
- 設定
- このモデルでは選ばない
- 使用条件
- モデルリポジトリにq8 ONNXファイルがなく、使用できません

localhostで開く静的HTMLを準備する
開始に必要なのは静的ファイル2つだけです。ES moduleのCDN importを使うため、ファイルを直接開かずローカルWebサーバーで配信します。以下のloopback `localhost`はWebGPUで必要なsecure contextとして扱われます。公開環境ではHTTPSを使ってください。初回にライブラリとモデルを取得するため、インターネット接続も必要です。
新しい空のフォルダーに`index.html`と`main.js`を作成し、以下のHTMLを保存します。これはjsDelivr CDNからライブラリをmoduleとして読み込む公式ドキュメントの方法に沿っています。URLでバージョンを固定することで、CDNの既定タグが変わってもこの例では4.3.0を指定できます。
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Browser-local text generation</title>
<label>Prompt <input id="prompt" value="Reply in one short sentence: local AI runs in a browser."></label>
<button id="run" disabled>Generate</button>
<pre id="status">Loading model…</pre>
<pre id="output"></pre>
<script type="module" src="./main.js"></script>
</html>
モデルを読み込み、一度生成する
以下の`main.js`はWebGPUを確認してからモデルを読み込みます。GPUアダプターが利用できれば`q4f16`、利用できない場合や確認中にエラーが起きた場合はCPU/WASM用の`q4`を選びます。準備ができるとGenerateボタンが有効になります。
初回はCDNからライブラリを、Hugging Face Hubからモデルファイルを取得します。この例では質問を別の推論サーバーに送らず、ブラウザー内で処理します。サービスに組み込む際は、分析やログ収集のコードが入力を送信していないかも確認してください。モデルは一度読み込み、ボタンを押すたびに同じpipelineを再利用します。
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.3.0';
const status = document.querySelector('#status');
const output = document.querySelector('#output');
const promptInput = document.querySelector('#prompt');
const button = document.querySelector('#run');
const modelId = 'onnx-community/LFM2.5-350M-ONNX';
let adapter = null;
try {
adapter = await navigator.gpu?.requestAdapter() ?? null;
} catch (error) {
console.warn('WebGPU unavailable; using CPU/WASM.', error);
}
const device = adapter ? 'webgpu' : undefined;
const dtype = adapter ? 'q4f16' : 'q4';
let generator;
try {
status.textContent = `Loading ${modelId} (${device ?? 'CPU/WASM'}, ${dtype})…`;
generator = await pipeline('text-generation', modelId, { dtype, ...(device ? { device } : {}) });
status.textContent = `Ready: ${device ?? 'CPU/WASM'} / ${dtype}`;
button.disabled = false;
} catch (error) {
status.textContent = `Model load failed: ${error.message}`;
console.error(error);
}
button.addEventListener('click', async () => {
if (!generator) return;
button.disabled = true;
status.textContent = 'Generating…';
try {
const result = await generator(promptInput.value, { max_new_tokens: 48 });
const generated = result[0]?.generated_text;
output.textContent = typeof generated === 'string'
? generated
: Array.isArray(generated)
? generated.at(-1)?.content ?? JSON.stringify(result)
: JSON.stringify(result);
status.textContent = 'Done.';
} catch (error) {
status.textContent = `Generation failed: ${error.message}`;
console.error(error);
} finally {
button.disabled = false;
}
});ページを配信し、結果と初回ダウンロードを確認する
ファイルを保存したフォルダーでターミナルを開き、以下のコマンドをどちらか一つ実行します。`http://127.0.0.1:8000`を開き、状態が`Ready:`になったらGenerateを押します。初回はモデルの取得に時間がかかります。準備が終わると、入力した文に対する短い結果が表示されます。
どちらのコマンドも、このコンピューターからだけ接続できるようにアドレスを限定しています。Node.jsなら一つ目、Pythonがあれば二つ目を選びます。公開サイトではHTTPSを使ってください。
# Option A: Node.js
npx serve --listen tcp://127.0.0.1:8000 .
# Option B: Python (choose one server, not both)
python3 -m http.server 8000 --bind 127.0.0.1モデルが開かないときは、ダウンロードとGPUエラーを確認します。
WebGPU adapterを取得できない場合はCPU/WASM用の`q4`を使います。SafariはTransformers.js 4.3.0で対応が追加されたSafari 26以降かを確認し、ほかのブラウザーでは該当バージョンのWebGPU対応を別途確認してください。adapterを取得できてもメモリ不足でモデルの読み込みに失敗する場合があります。
モデルファイルを読み込めない場合は、ブラウザー開発者ツールのNetworkでCDNまたはHubへのリクエストがブロック・失敗していないか確認します。GPU deviceエラーが出たら、ほかのタブやアプリを閉じてCPU5用`q4`で再試行するか、より小さな対応モデルを選んでください。入力後にエラーが出たら、最初のconsoleエラーとモデルID・dtype・deviceの組み合わせを記録すると再現に役立ちます。
ブラウザーでの抽出結果をJSON形式で受け取る
回答を別のプログラムに渡すときは、文章よりJSONが便利な場合があります。たとえば商品への意見から感情と話題だけを取り出せます。4.3.0の実験機能である構造化出力は、JSON Schemaでフィールドと値を制限します。現在は一度に一つの結果を生成します。
この機能には別のパッケージが必要です。以下のコードは先ほどのCDN HTMLに貼り付けず、ViteなどのモジュールバンドラーがあるWebプロジェクトで使います。依存パッケージを導入し、JavaScriptファイルにコードを追加します。結果は`JSON.parse()`で読み取り、必要なフィールドを確認してから利用してください。
npm install @huggingface/transformers@4.3.0 @huggingface/transformers-structured-outputimport { pipeline } from '@huggingface/transformers';
import { StructuredOutputProcessor } from '@huggingface/transformers-structured-output';
const generator = await pipeline('text-generation', 'onnx-community/LFM2.5-350M-ONNX', {
dtype: 'q4f16', device: 'webgpu',
});
const processor = new StructuredOutputProcessor(generator.tokenizer, {
type: 'json_schema',
json_schema: {
type: 'object',
properties: {
sentiment: { enum: ['positive', 'negative', 'neutral'] },
topic: { enum: ['price', 'quality', 'delivery', 'other'] },
},
required: ['sentiment', 'topic'],
additionalProperties: false,
},
});
const result = await generator(
[{ role: 'user', content: 'Classify this feedback: Shipping was fast, but the product is expensive.' }],
{ max_new_tokens: 48, do_sample: false, logits_processor: [processor] },
);
const jsonText = result[0].generated_text.at(-1).content;
console.log(JSON.parse(jsonText));用語の注釈
パイプライン — 入力から出力まで続く処理段階のまとまりです。段階ごとに異なるモデルやツールを使うことがあります。
本文に戻るWebGPU — ウェブブラウザーでグラフィックスや汎用GPU計算を行うための標準APIです。対応機能はブラウザーや端末によって異なることがあります。
本文に戻るシステムRAM — プログラムの実行中にデータを一時保存するシステムメモリです。
本文に戻るGPU — 多くの計算を並列に処理するプロセッサーです。AIモデルの実行ではモデル計算を担います。
本文に戻るCPU — コンピューターで汎用のプログラム命令を実行する中央処理装置です。AI処理ではGPUなど他のプロセッサーと役割を分けることがあります。
本文に戻る
