Skip to content

Suzumeブラウザで動く軽量日本語トークナイザー

WebAssembly にコンパイルした軽量トークナイザー。gzip 227KiB 以下で、サーバーも巨大な辞書もなしにクライアント側だけで動作します。

v0.9.9BetaApache-2.0 · オープンソース
227KiB
gzip 後のバンドル
生 555KiB
100%
クライアント完結
サーバー・API 不要
6
ランタイム
Browser · Node · Deno · Bun · Python · C/C++
ライブ

読むそばからトークナイズ

夏目漱石「吾輩は猫である」より
特徴

フロントエンドのための設計

サーバー・辞書・プライバシーの負担なしに、クライアント側で日本語をトークナイズできます。

小さなフットプリント

WASM モジュールと内蔵辞書を合わせて gzip 227KiB 以下。数十 MB の辞書を取得・配信する必要がありません。

クライアント完結の設計

ブラウザやランタイム上だけで動作します。トークナイズ用のサーバーも API 往復も CORS 設定も不要です。

テキストは手元に残る

解析は端末内で完結し、入力がブラウザの外に出ません。機微なテキストを自社インフラに預けずに済みます。

未知語に強い

単語の境界を固定辞書ではなく文字パターンから求めます。ブランド名・スラング・専門用語もそのまま残ります。

同期・即時

ネイティブに近い WASM 速度と同期 API。ネットワーク遅延なしで、キー入力ごとにトークナイズできます。

型付き・マルチランタイム

TypeScript の型を完備した C++ コア。Python・ネイティブ C/C++ で、バックエンド・バッチ・組み込みにも使えます。

プレイグラウンド

自分のテキストで試す

日常文・口語・方言・古語の例文を選ぶか、手元の文章を貼り付けて試せます。処理はブラウザ内で完結します。

読み込み中...
比較

Suzume の立ち位置

TinySegmenter の軽さと、MeCab に近い詳しさ。Suzume はその中間に位置します。

機能Intl.Segmenter 標準TinySegmenter 軽量Suzume kuromoji MeCab 高精度
ブラウザ動作
外部辞書の準備不要不要同梱必須必須
バンドルサイズ0KB~10KB227KiB~20MBN/A
サーバー不要
品詞情報
原形復元
複合名詞判定
カスタム辞書
未知語対応
比較表だけでは見えない、設計思想の違い分割単位・辞書への依存・未知語処理を具体例で解説します。MeCabとの違いを読む 速度と精度は?1回あたりのレイテンシ、初期化コスト、そして精度の数値が何を測っていて何を測っていないか。速度と精度を読む

インストール

bash
npm install @libraz/suzume
bash
yarn add @libraz/suzume
bash
pnpm add @libraz/suzume
bash
bun add @libraz/suzume
bash
pip install suzume
bash
git clone https://github.com/libraz/go-suzume.git
cd go-suzume && make lib
cd /path/to/your/module
go mod edit -replace github.com/libraz/go-suzume=/path/to/go-suzume
go get github.com/libraz/go-suzume
bash
git clone https://github.com/libraz/suzume.git
cd suzume && make install

Python 製のサービスやデータパイプラインでは Python バインディング、Go では Go バインディング、ネイティブ組み込みでは C / C++ ライブラリを参照してください。

使い方

各バインディングは、言語ごとの命名に合わせて同じ解析モデルを公開します。

typescript
import { Suzume } from '@libraz/suzume'

const suzume = await Suzume.create()

try {
  for (const m of suzume.analyze('東京都に住んでいます')) {
    console.log(m.surface, m.pos, m.baseForm)
  }
} finally {
  suzume.destroy()
}
python
from suzume import Suzume

with Suzume() as sz:
    for m in sz.analyze("東京都に住んでいます"):
        print(m.surface, m.pos, m.base_form)
go
package main

import (
  "fmt"
  "log"

  "github.com/libraz/go-suzume"
)

func main() {
  analyzer, err := suzume.New()
  if err != nil {
    log.Fatal(err)
  }
  defer analyzer.Close()

  for _, m := range analyzer.Analyze("東京都に住んでいます") {
    fmt.Println(m.Surface, m.POS, m.BaseForm)
  }
}
cpp
#include "suzume/suzume.hpp"
#include <cstdio>

int main() {
  suzume::Tokenizer tokenizer;
  for (const suzume::Morpheme& m : tokenizer.analyze("東京都に住んでいます"))
    std::printf("%s\t%s\t%s\n", m.surface.c_str(), m.pos.c_str(), m.base_form.c_str());
}

各トークンは表層形、品詞、原形、オフセットなどを持ちます。バインディングごとの名前は JavaScript/WASMPythonGoC / C++ の各リファレンスを参照してください。