測れていないものを閾値で追い込むと、必ず失敗する — 1日で10回踏んだ話
ある1日で、同じ形の失敗を10回踏んだ。自分で4回、並行して作業していたもう一方で7回(1件は共通)。分野はバラバラで、音声合成、検索、監査ログ、テキスト前処理、フレーム処理と重なっていない。それでも構造は同じだった。
指標が「0件」「一致しない」を返した。それを「対象が存在しない」と読んだ。 そして閾値やリストを絞る方向に手を入れ続けた。
対象は最初から観測系の外にあった。閾値をどう動かしても届くはずがない。
まず6件
① 音声モデルの語尾に付加音が出る
学習コーパスに幻覚が混ざったせいだと考え、台本突合の挿入許容を 3→1→0 と絞った。3回焼き直して、付加音は 3/6 → 2/6 → 3/6。誤差の範囲だった。
素材198本を波形で走査したら、付加音を持つ4本はすべて挿入0だった。STTが文字として拾わない音なので、閾値の分母に入っていない。
② 対話行為の判定が実会話で一度も発火しない
「質問かどうか」を語彙リストで判定していた。発火しないので語彙を足し、リストを絞り、条件を調整した。実際には複合発話(「これ何ですか、あと前のやつも」)を1件も判定できておらず、テスト用の単純文でしか通っていなかった。
③「根拠あり」の指標が常にTrue
回答に根拠を添えられたかを2値で測っていた。数値が良すぎるので閾値を厳しくした。実際には自動ページ案内がONだと常に何かが根拠として付くので、指標そのものが情報を持っていなかった。
④ 監査ログに navigate が0件
「勝手にページ遷移した」という報告に対し、監査テーブルを見て0件だったので「起きていない」と判断した。発行時に監査を残す実装が無かったので、そもそも記録されようがなかった。記録が無いことを、起きていないことの証拠として読んだわけだ。1回目の報告では誤診し、2回目の報告で初めて記録側を疑った。
⑤ ページの内容に答えられない
検索の閾値、除外条件、引き継ぎ判定と、4つのガードを足した。ユーザーに「そもそもページのテキストを全部把握しておくべきでは」と言われて、231字のページにベクトル検索を掛けていたことに気づいた。分割して検索する意味がない長さで、そのうえ前処理で文字が落ちて検索を外していた。
⑥ 発音が崩れる
「少々お待ちください」が「しょもおまちください」と聞こえる。モデル→合成パラメータ→キャッシュ→経路と順に潰していった。最後に前処理の出力を1回 print したら、こうだった。
_clean_tts_text('少々お待ちください。') → '少お待ちください。'
許可文字のホワイトリストで漢字の範囲を 一-鿿 としていて、「々」は 々(CJK記号ブロック)なので落ちていた。少お待ちください を合成すると「ショーをお待ちください」と読まれる。
さらに4件(同じ日の後半)
記事を書いている間に、並行していた側からもう4件届いた。すべて同じ型だった。
- フレームの型を取り違えて、ゲートが一度も動いていなかった(実機ログが0件で発覚)
- 偽のVADでは通り、本物には属性が無くて何もしていなかった
- 巨大プロンプトの末尾に指示を置いて、4回とも無視された(同じ知見が同じファイルに書いてあった)
elapsed_msが何を測っているか取り違えて、直す必要のないものを直しかけた
本人の総括はこうだった。
共通しているのは「テストは緑、実機のログで初めて分かる」です。
1つ目は特に厳しい。ゲートを作り、テストを書き、8/8で通し、デプロイして、一度も動いていなかった。テストは自分が想定したフレームで書いているので、実物と型が違えば両方とも同じ勘違いの上に乗る。
共通する形
並べると3つの層がある。
層1: 「0件」を証拠として読んだ
①では「STTで検出0件だから付加音はない」、④では「監査0件だから遷移していない」。どちらも観測系が壊れていれば同じ0件が出るのに、正常な観測系を前提に読んだ。
0件は「無い」の証拠にならない。「観測系が生きていて、かつ対象が無い」ときにも、「観測系が死んでいる」ときにも、同じ0が出る。この2つを区別する情報が0件という値には含まれていない。
層2: 症状の側にガードを足し続けた
②は語彙を足し、③は閾値を厳しくし、⑤は4つのガードを足した。どれも症状が出ている場所の近くをいじっている。
これは合理的に見える。症状の近くは原因の近くだろう、という直感がある。だが観測できていない対象が相手だと、症状の近くをいくら固めても効かない。①は閾値を3回動かして、効果は誤差の範囲だった。
層3: 自分が作った観測系を疑わなかった
ここが一番深い。
- ①の品質ゲートは私が書いた。だから「ゲートを通ったのだから素材は正常」と考えた
- ④の監査ログは相手が入れた。だから「入れたから見えているはず」と考えた
- ③の指標も、⑤の検索も、作った本人が疑っていない
自分が作ったものは、動作を確認した記憶があるぶん、疑いにくい。 そして疑わないので、その外側を見ない。
②〜④を踏んだ側は、「パイプライン失敗の可視化」を作った翌日にそのパネル自体が404していたことにも気づいていなかった。作って、動くのを見て、それで終わりにしている。
抜け出せたときに効いた、唯一の手
自力で抜けられたものには共通点があった。観測の軸を変えて、同じ対象をもう一度測っている。
| 件 | 元の軸 | 変えた軸 | 結果 |
|---|---|---|---|
| ① 付加音 | STTの書き起こし | 波形の包絡 | 挿入0のクリップに4本の付加音を発見 |
| ⑤ ページ | 検索スコア | 文字数を数える | 231字だった |
| ⑥ 発音 | 合成音声を聴く | 前処理の出力をprint | 「々」が消えていた |
どれも5分以下の作業だ。①の波形走査は30分かかったが、それでも閾値を3回動かして焼き直した時間の10分の1以下だった。
指標の自己検証は原理的に難しい。 指標が壊れているかどうかを、同じ指標では確かめられない。だから「この指標は正しいか」と考えるより、別の物差しを1回当てるほうが早い。
人の報告は、独立した観測系
もう一つ、全件を通して効いた見方がある。
指標と人の報告が食い違ったら、指標を先に疑う。
①では、ユーザーから「『こちらですって』と聞こえる」という報告を受けた後も、私は「STTで0/6だから引き継がれていない」と自分の測定を上に置いた。耳という別の観測系が既に結果を出していたのに。
④も同じで、1回目のユーザー報告を監査0件で退けている。
人の報告は主観的で曖昧だから、機械の指標より弱い証拠だと扱われやすい。だが独立した観測系であるという一点で、食い違ったときの価値は高い。同じ対象を別の軸で測った結果が2つあり、片方が「異常」と言っているなら、まず疑うべきは自分の計器だ。
実務に落とすなら
ここから抽出できた手順はこうなる。特別なことは何もない。
閾値を触る前に、その閾値で対象を観測できているかを1回問う。 ①で言えば「挿入0のクリップに付加音があり得るか?」。1回問えば波形で見る発想が出た。
「0件」を見たら、記録が生きていることを別経路で確認する。 ④で言えば「監査を1件でも意図的に発生させて、記録されるかを見る」。5分で済む。
症状側に2つ目のガードを足す前に、川上を1回見る。 ⑤で言えば「ページの文字数を数える」。1つ目のガードで直らなかった時点で、そのガードが対象を捉えていない可能性が出ている。
検出器を作ったら、引っかかってはいけないもので先に試す。 ①の波形検出器は、最初12モデル全部を「異常」と判定した。読点のポーズを付加音と誤検出していた。検出率が高すぎるときは、対象ではなく検出器を疑う。
自分が作った観測系ほど、別の軸で1回裏を取る。 これが一番効く。作った直後に1回やっておけば、①は3回の焼き直しが要らなかった。
名前を調べる
最後に、振り返って一番悔しかったこと。
ほぼ全部が既知の定型問題だった。
音声の付加音は trailing artifact / babbling として知られている。「移動しますね」と言って移動しない現象には procedural hallucination という名前があり、専用のベンチマークまである。自己エコー対策の「発話終了後のマイクゲートは300msでは足りず500〜800ms必要」も、定説として書かれている。
私たちは全部を自分の環境固有の問題として扱い、内側だけを掘った。症状に名前が付いていないかを最初に調べていれば、「STTでは検出できない」という既知の性質にもっと早く辿り着けたはずだ。
「1日で10回踏んだ」と書いたが、正確には10回とも、外を見れば先例があった。
シリーズ: 拡散TTSから実用ボイスを量産する
キャプション1行から声を設計し、学習コーパスを製造して、役割別の実用ボイスを量産するまでの記録です。この記事は第5部 総括にあたります。
← 前: デプロイのたびに互いの成果を消していた (シリーズはここまで)
シリーズ全18本
- 音質で選んだTTSが、会話には遅すぎた
- 声をガチャで引く
- 「ナレーターっぽい声」を24候補から機械に選ばせる
- 品質ゲートを厳しくするほど、棒読みが生き残る
- 学習後に話速は変えられない
- 生成するたび「録音場所」が変わるTTS
- クリップ1本の粗さが、スタイル全体を嗄れさせる
- AIが「こんにちわー」と伸ばす癖は、どこで身についたのか
- 「少々」が「しょも」になる — 許可文字リストが日本語を削っていた
- ハルシネーション対策のコードが、ハルシネーションの時だけ動かなかった
- 品質ゲートが許した「3文字」が、モデルの口癖になった
- 治せる欠陥で候補を落としていた
- 文字起こしでは見つからない欠陥がある
- 70分かけた学習素材が、ネットワークの一瞬の瞬きで消えた
- “ja” を “JP” と書いて喃語モデルができるまで
- 登録経路が4つ、管理画面が0
- デプロイのたびに互いの成果を消していた 18. 測れていないものを閾値で追い込むと、必ず失敗する ← いまここ
知見の元になったノートは 拡散TTSから実用ボイスを量産する製造パイプライン にまとめてあります。