AWSでSpot Instances、SQSキューを用いたオートスケーリング、Whisper Large-v3 Turboを活用し、OpenAI Whisper APIより安価なコスト最適化されたセルフホストAI文字起こしパイプラインを構築する深掘り解説。
音声-to-テキストを基盤に構築するほとんどのチームは、API利用料を静かに受け入れている。私はそうしなかった。サイドプロジェクトで月額$180の文字起こしAPI料金がかかるようになり、AWS上にパイプライン全体を再構築して処理コストを$0.10/時間未満に抑えた。これはOpenAI Whisper API自体より安い。
本記事では、アーキテクチャ、トレードオフ、および成功につながった具体的な判断を順に解説する。ここで紹介する内容は、私がソロファウンダーとして構築したAI文字起こしプラットフォームStrikeScribeの実際のプロダクション負荷に基づくものであり、ベンチマークのおもちゃではない。
Whisper、Deepgram、AssemblyAI、またはOpenAI Audio APIの上に何かを構築しているなら、これは大多数の人が見逃している裁定取引だ。
問題:マネージド文字起こしAPIはコスト面でスケールしない
マネージドAPIは使い始めるには素晴らしい。音声を送ればテキストが返ってくる。ただし、価格モデルはボリュームを罰する:
- OpenAI Whisper API: 約$0.36/時間($0.006/分の場合)
- Otter、Firefliesなど: 利用時間を制限し超過分には高額な追加料金を請求するサブスクリプション階層
- AssemblyAI / Deepgram: 競争力はあるが、利用量に比例して直線的に増加する従量課金
月間数百時間の処理(ミーティング、ポッドキャスト、リサーチコール、IoT音声ストリームなど)を行う段階になると、この線形コスト曲線が支配的なコスト項目になる。直接借りられるGPUコンピュートに対して他者のマージンを支払っていることになる。
洞察:基盤モデル(Whisper)はオープンソースである。 支払っているのは他者の利便性レイヤーだ。自身で効率的に推論を実行できれば、経済性が逆転する。
アーキテクチャ
ハイレベルなパイプラインは以下の通り:
Upload → S3 → SQS Queue → Autoscaling Worker Group (GPU Spot Instances)
→ Whisper Large-v3 Turbo → Pyannote (diarization) → Postgres → Client
Enter fullscreen mode Exit fullscreen mode
コストに実際に影響する部分を分解する。
1. 品質と速度のスイートスポットとなるWhisper Large-v3 Turbo
Whisper Large-v3 Turboは、Large-v3に近い精度を推論時間の大幅な削減で実現する。コスト重視のパイプラインでは、推論速度がそのままコストになる。GPU秒単位で課金されるためだ。Turboはオーディオ時間あたりの秒数を劇的に削減する。
より高速なスループットのため、参考実装よりメモリ・計算効率が大幅に優れたfaster-whisper(CTranslate2バックエンド)で実行している:
from faster_whisper import WhisperModel
# int8_float16 keeps VRAM low while preserving accuracy
model = WhisperModel(
"large-v3",
device="cuda",
compute_type="int8_float16",
)
segments, info = model.transcribe(
"audio.wav",
beam_size=5,
vad_filter=True, # skip silence, save compute
vad_parameters={"min_silence_duration_ms": 500},
)
for segment in segments:
print(f"[{segment.start:.2f} -> {segment.end:.2f}] {segment.text}")
Enter fullscreen mode Exit fullscreen mode
安価に得られる2つの勝ち:
-
vad_filter=True— 音声アクティビティ検出により無音区間を完全にスキップする。実際の録音(ミーティング、通話)は無音だらけで、この機能だけで計算量を大幅に削減できた。 -
int8_float16量子化 — VRAMの少ない安価なGPUでもLarge-v3を実行可能にし、ほとんどの音声で精度低下をほとんど感じさせない。
2. SQS + キューの深さによるオートスケーリング
素朴なアプローチは常に稼働するGPUインスタンスを1台用意することだ。これは高くつく — アイドル時間にも課金される。
代わりに、アップロードと処理をSQSキューで分離する。軽量なNode.jsコントローラがキューの深さをポーリングし、バックログに応じてワーカーフリートをスケーリングする:
import { SQSClient, GetQueueAttributesCommand } from "@aws-sdk/client-sqs";
import { AutoScalingClient, SetDesiredCapacityCommand } from "@aws-sdk/client-auto-scaling";
const sqs = new SQSClient({ region: "us-east-1" });
const asg = new AutoScalingClient({ region: "us-east-1" });
async function scaleWorkers() {
const { Attributes } = await sqs.send(
new GetQueueAttributesCommand({
QueueUrl: process.env.QUEUE_URL,
AttributeNames: ["ApproximateNumberOfMessages"],
})
);
const backlog = parseInt(Attributes.ApproximateNumberOfMessages, 10);
// one worker per N queued jobs, capped to control spend
const desired = Math.min(Math.ceil(backlog / 5), MAX_WORKERS);
await asg.send(
new SetDesiredCapacityCommand({
AutoScalingGroupName: process.env.ASG_NAME,
DesiredCapacity: desired,
})
);
}
Enter fullscreen mode Exit fullscreen mode
キューが空になると、フリートはGPUワーカーをゼロまでスケールダウンする。音声処理があるときのみGPU時間に対して課金される。これが構造的なコスト削減で最も大きなレバーだ。
3. Spot Instances(および中断への対応)
GPU Spot Instancesはオンデマンドより60〜90%安価だ。欠点は、AWSが2分前に警告してインスタンスを回収できる点にある。ステートレスなバッチワークロードである文字起こしにとっては、これは理想的な適合だ — 中断を適切に処理できれば。
ワーカーはSpot中断通知を監視し、実行中のジョブをキューに戻すことで、仕事を失わないようにしている:
// Poll the instance metadata endpoint for the interruption signal
async function checkForInterruption() {
try {
const res = await fetch(
"http://169.254.169.254/latest/meta-data/spot/instance-action",
{ signal: AbortSignal.timeout(1000) }
);
if (res.status === 200) {
// Reclaim imminent — put the current job back on the queue
await requeueCurrentJob();
await gracefulShutdown();
}
} catch {
// 404 = not interrupted, carry on
}
}
setInterval(checkForInterruption, 5000);
Enter fullscreen mode Exit fullscreen mode
ジョブはべき等性を持ちキューで管理されているため、中断されたジョブは別のワーカーが引き継ぐ。作業が失われることはなく、手動復旧も不要だ。この耐障害性が、Spotを趣味のバッチジョブだけでなく本番環境でも実用可能にする。
4. Pyannoteによるダイアライゼーション
生の文字起こしは価値の半分に過ぎない — 誰が何を言ったかを知ることが、テキストの壁を有用な議事録に変える。Pyannoteが話者ダイアライゼーションを担う:
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token=HF_TOKEN,
)
diarization = pipeline("audio.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"{speaker}: {turn.start:.1f}s - {turn.end:.1f}s")
Enter fullscreen mode Exit fullscreen mode
ダイアライゼーションセグメントとWhisperのタイムスタンプを揃えることで、各行に話者を割り当てることができる。計算量は増えるが、「文字起こし」と「ミーティングインテリジェンス」の違いを生む。
結果
本番環境でのパイプライン運用結果:
- 処理コスト:オーディオ1時間あたり$0.10未満 — OpenAI Whisper APIを下回る
- ストレステスト:9台のRaspberry Piが24時間365日録音した216時間の音声を合計$3未満で処理
- 常に稼働するマネージドAPIベースラインと比べて、全体的なインフラコストを約60%削減
4つのレバー — Turboモデル、VADによる無音スキップ、スケール・トゥ・ゼロのオートスケーリング、Spot料金 — の複合効果は加算ではなく乗算だ。1つだけでも効果があるが、組み合わせることでユニットエコノミクス全体が変わる。
セルフホストすべきでないケース
公平に言うと、これはただの無料ランチではない。セルフホストが私にとって理にかなった理由は以下の通りだ:
- API料金がエンジニアリング時間を上回るほどボリュームが多かった
- ワークロードがバッチであり、リアルタイムではなかった(Spot+キュー遅延は許容範囲)
- AWSインフラ、GPUドライバ、モデル更新の運用に抵抗がなかった
ボリュームが少なく、サブ秒のライブキャプションが必要な場合、またはインフラの運用を望まない場合は、マネージドAPIが適切な選択肢だ。損益分岐点は通常、月間数百時間程度のところにある。
まとめ
競合他社が過剰に価格設定しているものを見つけ、自分がコントロールできるプリミティブでより安く構築する — この裁定取引モデルは、現在AIインフラ分野で現実のものとなっている。「AIプロダクト」の価格の多くは、GPUコンピュートとオープンモデルの上に載るマージンに過ぎない。
意味のある音声ボリュームを処理している場合、私の手法は以下の通りだ:
-
faster-whisper+ Large-v3 Turbo(int8_float16およびVAD併用) - ゼロまでスケールダウンするSQSキューの深さベースオートスケーリング
- 中断耐性とべき等性を持つGPU Spot Instances
- 実用的な製品価値を加えるPyannoteによるダイアライゼーション
これらすべてをStrikeScribeに組み込んだ — 音声または動画をアップロードするだけで、検索可能な文字起こしと構造化されたAIインサイトを取得できる。サインアップやミーティングボットは不要だ。このパイプラインの出力側を実際に確認したい場合は、これが最も簡単な方法だ。
特にSpot中断処理やダイアライゼーションのアライメント — 通常、人々が詰まりやすい2点 — について、アーキテクチャに関する質問をコメントで歓迎する。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.