2025-01-13 (Mon) [長年日記]

_ [srv] ささやいてました

  • Apple Silicon を入手して whisper.cpp の examples/stream色々やっていた
    • どの程度の性能が必要なのか心配していたが……
      • Mac mini M4 16GB なら余裕すぎ
        • whisper を動かしていてもいなくても非常に省電力なので、他の用途でも、つけっぱなしで動かすときには結局 N100 とかを買うより電力や静音の面で良いという場合も多そう
      • Macbook Air M2 8GB でも、一番重いはずの v3 (非 turbo) で 10秒の音声を 1秒ぐらいで扱えるから stream でガンガンまわすことができる
    • Mac mini を家に置いたまま WebSocket でブラウザの getUserMedia から音声を受け取 (って ffmpeg で Float32 の PCM に変換す) るサーバを Deno で書いてたら、Deno のバグ に引っかかったぽくて、静かに止まってしまうので、Python で書いた
      • シェルでは nc | ffmpeg | stream ってパイプでつなぐだけって感じだけど、Python 等でやると少しコツが必要だと感じた
        • きっともっとシンプルにできるんだろうなぁ
      • whisper は sample rate が 16000 だけど、ブラウザの音質はそれに合わせるより、まず 48000 とかで取得して流すほうが良いみたい
      • 16000 だと認識精度が落ちるほどになった
    • whisper はリトルエンディアンの Float32 (4 バイト) PCM が必要なんだけど、ネットワーク越しとかパイプ越しでやっているうちに 1〜3 バイトずれることがあっても whisper は認識してくれているような気がする
      • tee したデータファイルを見てみると接続のたびにズレてるけど、whisper は普通に日本語の結果を出してくれてる (もしかすると一瞬戸惑ってからだったかもしれない)
      • だから 4 の倍数にすることをそれほど気にしなくてもいいのかも

今回は Windows PC が相次いで故障したので失敗したくなくて、 安く確実に whisper を使えるだろうということで M4 Mac mini にしたけど、 Ryzen とかでも VRAM を設定して普通に使えたりするんだろうか

  • whisper は音量にはとても寛容
    • 音割れしても小声でも認識精度はそれほど落ちない
    • だから無音の区間でも幻聴で「おやすみ」とか「ご静聴ありがとう」とか言い出す
      • そこをどうするかについて決定打はないみたい
      • VAD を使って、いい感じの区間だけ取り出すのがひとまずの最善と考えられているんだろうとは思う

_ [srv] 認識結果を手作業で直しつつ難聴の人に見せたいと思った

  • クラウドに出したくない会話内容とかネット環境の悪い場所とかのために HedgeDoc も検討したけど、パッチを当てるのが難しいのでやめて Rustpad にした
    • Rustpad のクライアントは手抜きで書いたのでそれほど複雑にならなかったけど、(WebSocket で現在の文書の内容や長さを一発確認する API がないみたいだから) 毎回普通の http で GET するとかいうダサいことをしていて人に見せたくない
    • History の operations で変更をぜんぶ追えばいいんだろうけど、それも面倒だし……
  • Google Docs は JSON でドバーッと返してくれるのはいいけど、テキストを取るだけでもダルい
   doc = google.service.documents().get(documentId=DOCUMENT_ID).execute()
   bodyContent = doc["body"]["content"]
   return reduce(
       lambda a, b: a + (b["textRun"]["content"] if "textRun" in b else ""),
       bodyContent[index]["paragraph"]["elements"],
       "",
   )

🙄段落ひとつ取り出すだけでも content の paragraph の element の textRun の content を連結しなきゃいけないの?

_ [js][srv] もう IPv4 でサーバ立てるのも面倒なので、noip.com に AAAA を登録してみようと思った

  • A が消せないのね
  • HTML の JS から扱うなら、DNS API で AAAA だけ取るなどして対応
   await fetch(
     "https://dns.google/resolve?name=example.com&type=AAAA"
   ).then((response) => {
     return response.json();
   }).then((json) => {
     return json.Answer[0].data;

_ [js] そういえば copilot とかは便利

  • Zed で有効にして編集してたら、上記の後半は勝手に出してくれた
  • Answer[0].data のためにぐぐる必要はもうない
    • ウソも多いけど、かなりいい感じに空気を読んでくれて気持ちいい
    • 「pyaudio でマイクから音声を拾って websocket で送るには?」みたいな質問もだいたい答えてくれる
    • 今どきの実装じゃなかったり、要らないことをしていたりとかポンコツなこともあるけど、自分でゼロからやるよりはずっと早い

«前の日記(2024-05-28 (Tue)) 最新