Share
Embed
Jetson Orin Nanoとk3sとローカルLLMで音声文字起こしシステム作ってみた
2026/10/6
Kubernetes Novice Tokyo #42
世良泰明
October 06, 2026
Transcript
15 slides
-
自己紹介 名前: 世良泰明(せら やすあき) 職業: インフラエンジニア(?) k8sを使って開発するお仕事 某製造業@横浜 社会人6年目 趣味:
囲碁, 散歩, etc... twitter: @y_sera15 自宅K8sクラスター Intel NUC 3台 + Synology NAS -
今日の話 • Jetson Orin Nano + k3s + LLMで音声認識アプリを作った話 文字起こし
ログ システム構成 Generic Device Plugin 音声入力 アプリ lamma.cpp server .wav転送 文字起こし 結果 k3s /dev/snd/* USBマイク Jetson Linux + Jetpack7.2 Jetson Orin Nano hostPath Gemma4 E2B -
構成要素 Jetson Orin Nano k3s • Nvidia製のシングルボードコンピュータ • エッジ向け軽量Kubernetes •
GPUと8GBのユニファイドメモリ • Ubuntuベースの専用OSで稼働 • シングルバイナリ + コンテナで構成 Gemma4 llama.cpp • LLMを動かすための軽量な推論エンジン • Google製LLMのモデル • 音声 → テキストも処理可能 • 今回は軽量なgemma4-E2B-it-qat-q4_0を使用 -
Generic Device Plugin Linuxの汎用的なデバイスをKubernetesのPodにマウントする仕組みを提供するOSS - シリアルデバイス - FUSEデバイス - ビデオカメラ
などなど インストールコマンド kubectl apply -f \ https://raw.githubusercontent.com/squat/generic-device-plugin/main/manifests/generic-device-plugin.yaml -
Generic Device Plugin Linuxの汎用的なデバイスをKubernetesのPodにマウントする仕組みを提供するOSS 許可するデバイスのパスとカテゴリを引数で指定 generic-device-pluginの引数 containers: - image: squat/generic-device-plugin
args: - --device -| name: serial groups: - paths: - path: /dev/ttyUSB* ... - --device -| name: audio groups: - count: 10 paths: - path: /dev/snd ... アプリのマニフェスト apiVersion: apps/v1 kind: Deployment metadata: name: audio-app spec: ... template: ... spec: containers: - image: audio-app:latest resources: limits: devic.es/audio: 1 -
Device Plugin Kubernetesがデバイスを管理する仕組み DevicePluginのpodが特権を持って デバイスをkubeletに広報 ワークロードのpodによる要求に応じて 必要なデバイスだけランタイムが割り当て 図の引用元 https://developers.redhat.com/articles/2025/11/12/newmicroshift-4-20-generic-device-plugin# 公式ドキュメント(Englishのみ)
https://kubernetes.io/docs/concepts/extendkubernetes/compute-storage-net/device-plugins/ -
ハマりポイント USBデバイスは、マウントするたびに/dev/のパスが変わる パス: /dev/snd/pcmCXDYp 最初決め打ちしていたが、再起動でマイクが迷子に → 一通りデバイスをサーチしたのち、 デバイス情報が “USB Microphone”となっているものを選択
def find_audio_device(pa): for i in range(pa.get_device_count()): info = pa.get_device_info_by_index(i) if ( info["maxInputChannels"] > 0 and "USB Microphone" in info["name"] ): return i raise RuntimeError("USB Microphone not found") -
今日の話 • Jetson Orin Nano + k3s + LLMで音声認識アプリを作った話 文字起こし
ログ システム構成 Generic Device Plugin 音声入力 アプリ lamma.cpp server .wav転送 文字起こし 結果 k3s /dev/snd/* USBマイク Jetson Linux + Jetpack7.2 Jetson Orin Nano hostPath Gemma4 E2B -
LLMのホスト LLMの処理はGPUを使いたい - 昨今だとDRAとかあるけど、GPU分割するほどリッチな環境じゃない - nvidia-device-pluginとかあるけど, いらないもの入れたくない... runtimeClassNameでNvidiaを指定 → k3sはnvidiaのランタイムを見つけると
自動でnvidia runtimeClassを作成 apiVersion: apps/v1 kind: Deployment metadata: name: gemma4-e2b spec: ... template: ... spec: runtimeClassName: nvidia containers: - image: ghcr.io/ggml-org/llama.cpp:server-cuda13 ... -
ハマりポイント cudaのバージョン差異 フォーラムリンク 起動時の互換性チェックで失敗 https://forums.developer.nvidia.com/t/cuda-13-2-1-runtimeimage-cant-run-on-r39-2-sample-rootfs-for-orinnano/372683/19 - Jetson OS(Jetpack7.2)のバージョン(最新): 13.2 -
llama.cpp cuda版のイメージ: 13.3 → 公式フォーラム 「ドライバの許可リストミスってるので、バージョン無視で対応可(意訳)」 ⇨ 環境変数: NVIDIA_DISABLE_REQUIRE=true で無事起動 マルチモーダル(音声・画像など)な入力対応 - マルチモーダルではメインのggufファイルだけでなくmmproj.ggufを読み込む必要あり -
その他細かい工夫点 メモリ領域との戦い llama.cpp + Gemma4が大きく、 しばらくするとOOMを起こす → パラメータを細かく調整しメモリ削減 ギリギリだけど継続的に稼働するように #
Thinkingしない LLAMA_ARG_REASONING=off # キャッシュ周りをオフ LLAMA_ARG_CACHE_PROMPT="false" LLAMA_ARG_CACHE_RAM="0" LLAMA_ARG_CACHE_IDLE_SLOTS="false" # キャッシュの量子化 LLAMA_ARG_CACHE_TYPE_K="q8_0" LLAMA_ARG_CACHE_TYPE_V="q8_0" # 並列をしない LLAMA_ARG_N_PARALLEL="1” # コンテキストサイズ短めに LLAMA_ARG_CTX_SIZE="2048” -
まとめ Jetson Orin Nano + k3sをベースに、文字起こしシステムを作った。 - USBデバイスをpodにマウント -> Generic
Device Plugin - llama.cppでLLMをホスト -> Nvidia Runtime - その他細つまづきポイントを共有 ただ最近、litert-lmというgoogle謹製の推論エンジンを発見 まだまだメモリが厳しい(100MiB程度の空きしかない)ので、次はこれをトライ -
発表後 FAQ Q: Device PluginではなくDRAを使うことは 可能なのでしょうか? (最近流行っている印象なので無邪気な質問です) A. 結論: Jetson
Orin Nanoでは、現在は不可のようです 現在サポートされているもの: dGPU Jetson Orin Nanoの構成: L4T(Tegraデバイス) これらは全く異なるスタックであり、 大幅なアーキテクチャ変更が必要になるとのこと dGPU, L4T, Tegraが何かは私はよく分かってないですが... https://github.com/kubernetes-sigs/dradriver-nvidia-gpu/discussions/730