ローカルLLMを利用しているため、ライブ変換の動作は非常に快適である。これまでMacにおける、入力と同時に次々と変換される様子を羨ましく感じていたが、Karukanではそれ以上に扱いやすい印象を受ける。
もっとも、ローカルLLMを使用している以上、モデルの読み込みに一定の時間を要する点は避けられない。また、現時点では細部の調整が十分とは言えず、操作中に戸惑う場面も存在する。しかし、それらは致命的な問題というより、使用に慣れることで吸収できる範囲に収まっているように思われる。
さらに、MeCabのような形態素解析を組み合わせれば、入力体験は一段と向上する可能性がある。ただし、全体のパフォーマンスとの兼ね合いにおいて、どの程度の効果が得られるのかは現段階では判断が難しい。
そこで試験的に、いくつかの改良を加えてみた。なお実際の改修作業を行ったのはClaudeであり、筆者自身はコードを直接記述していない。また、短期間に多数の変更を加えた結果、全体のバランスがやや崩れている印象も否めない。この状態のまま公開することには、多少の不安が残る。
本来、この種のアプリケーションを適切に改善していくためには、実行状態をモニタリングし、動作特性を分析するプロファイリング作業が不可欠である。しかしプロファイリングには高度な知識と体系的な検証作業が求められ、現状のAIが自律的に十分実施できる段階には至っていない。
そのため今回は、完成したコードそのものではなく、改修の結果から見えてきた方向性のみを公開することとした。
Karukan 変更まとめ
設定基盤の再構築
-
~/.config/karukan-im/config.tomlで全パラメータを外部設定可能に(オリジナルはハードコード) -
Settings構造体でConversion/Learning/Keybindingを管理、default.tomlをバイナリ埋め込み - キーバインドをテーブル駆動方式に刷新。各アクションに複数キー割当可能、修飾キー単押し対応
入力モードの拡張
- 2モード(ひらがな/英字)→ 4モード(ひらがな/カタカナ/英字/直接入力)に拡張
- ライブ変換: 入力中にリアルタイムで漢字変換結果をpreeditに表示(macOS日本語入力風)
- Ctrl+Shift+Lでトグル、
config.tomlのlive_conversion = true/falseで起動時設定可能 - ライブ変換中は候補ウィンドウを非表示(Space押下の明示的変換時のみ表示)
辞書システム
- Mozc辞書統合: TSV形式を直接ロード、MAX_COST 7000フィルタで約48万件に最適化
- mmap V2フォーマット: メモリマップによる遅延ロードで起動時の辞書読み込みが数百ms→数msに
-
AnyDictenumでV1(ヒープ)/V2(mmap)を透過的に扱い、複数辞書のマージにも対応 - ユーザー辞書:
~/.local/share/karukan-im/user_dicts/内のファイルを自動スキャン・自動判別 - 予測入力: 入力途中の読みに対して前方一致で辞書候補を表示(学習→完全一致→予測の優先順)
-
max_dict_candidates(デフォルト20)でソースごとの候補数を制限
学習システム
-
LearningCache: ユーザーの変換選択を記録、スコアrecency * 10.0 + ln(1 + frequency)で順位付け - Bigram学習: 「前の確定語→今の読み→今の候補」の3つ組を記録し文脈に応じた候補優先
- TSVファイルで永続化、最大10,000エントリでスコア最低のものからevict(bigram含む統合eviction)
- deactivate時およびエンジン破棄時に自動保存
推論最適化
- バックグラウンドモデルプリロード: 別スレッドでメイン(85MB)+ライト(30MB)モデルを非同期ロード
- ノンブロッキング初期化:
is_finished()で完了確認、未完了なら即リターン → fcitx5メインスレッドをブロックしない(他アプリのフリーズ解消) - activate(Ctrl+Space)時に初期化開始し、ユーザーがタイピングを始めるまでにロード完了を目指す
- 推論キャッシュ: 同一入力の再変換を即返し(上限128エントリ)
- 変換ストラテジー: Adaptive/Light/Mainの3モード、入力長やレイテンシに応じて動的切替
fcitx5アドオン(C++層)
-
std::thread+std::atomic<bool>でバックグラウンド初期化 - ロード状態通知: 辞書ロード中は
Karukan: Loading...、モデルプリロード中は⏳ Loading...、完了後はモデル名表示 - 初期化中のキーイベントは素通し
