1仕組みと動作原理
中核となる知識は 2.5 世代における2つの大きな変更点です。voice_label が廃止され(自然言語 instruction ≤200文字 + テキスト内インライン () プロソディ指示へ変更)、検閲が厳格化されました(死/消失/センシティブな政治用語が censorship_block をトリガー)。
**What `stepaudio-2.5-tts` will NOT accept** — `voice_label` parameter. Error: `voice_label is not supported for v2 models`. This is the #1 migration gotcha from step-tts-2.
スクリプトが /v1/audio/speech にリクエストを送信:JSON body(model/input/voice/response_format/speed/volume + 任意の instruction)、Authorization Bearer を設定し、成功時は mp3 バイト列をディスクへ直接書き込みます。
body: dict[str, Any] = { "model": MODEL, "input": text, "voice": voice, "response_format": response_format, "speed": speed, "volume": volume, }
instruction 長の厳格な検証 + テキスト透過によるインライン () プロソディ制御:文内の (试探着问)/(轻声)/(停顿一下) などの括弧内コンテンツはモデルに演技指示として解釈され、読み上げからは除外されます。
if instruction: if len(instruction) > 200: return {"ok": False, "status": 0, "err": f"instruction too long: {len(instruction)} > 200 chars"}
censorship_block に対する行単位のフォールバック:'censorship_block'/'blocked' を検知して失敗行をマークし、バッチモードではスキップした ID を記録して処理を継続、バッチ全体の停止を防ぎます。
censored = "censorship_block" in raw or "blocked" in raw.lower()
バッチ処理:--batch で JSONL(1行1オブジェクト:{id, text, instruction?})を読み込み、--out-dir/<id>.mp3 へ1行ずつ合成、行間に sleep delay-ms を設けてレートリミットを回避します。
out_path = args.out_dir / f"{line_id}.mp3" if result["ok"]: out_path.write_bytes(result["audio_bytes"])
非破壊 A/B テストの設計不変条件:再生成されたコーパスは並行ディレクトリ(voice/zh_v25/)に書き込み、本番資産を上書きしません。ab_compare.sh は ffprobe/stat を用いて両ディレクトリの mp3 のサイズおよび再生時間を比較し、Markdown テーブルを出力します。
1. **Non-destructive A/B output** — when regenerating a corpus with a new model, write to a parallel directory (`voice/zh_v25/`), never overwrite the production corpus.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| network | api.stepfun.com(StepAudio TTS 端点) |
| network | platform.stepfun.com(取 key/定价/voice 文档,仅指引) |
| cli | python3(stdlib urllib,无第三方包) |
| cli | ffprobe(ffmpeg,ab_compare 用) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: daymade-audio/stepfun-tts/scripts/tts_generate.py
- 网络端点: 外部ネットワークアクセスの宣言: POST https://api.stepfun.com/v1/audio/speech(リクエストボディに合成対象テキスト + instruction + Auth を含む)
- 本地工作目录: ファイルの読み書きおよび成果物の出力: tts_generate.py がユーザー指定パスに --out(単文)または --out-dir/<id>.mp3(バッチ、mkdir parents)を出力
5二重目の独立検証
- [ok] 端点/body/模型名(/v1/audio/speech + stepaudio-2.5-tts) — tts_generate.py API_URL/MODEL 常量与 body dict 逐字存在;api_reference.md 同。
- [ok] voice_label 拒绝处理(迁移 gotcha) — 脚本对 raw 含 'voice_label is not supported' 时追加 HINT 文案;SKILL.md 错误表同描述。
- [ok] instruction ≤200 硬校验 — synthesize() 内 'if len(instruction) > 200: return {ok: False, status: 0, err: ...}' 存在,超长不发请求。
- [ok] censorship 逐行降级(不整批失败) — censored 列表单独收集、failed 汇总、循环 continue;main 返回码只按 failed 定。
- [ok] API key 解析(env → CLAUDE_PLUGIN_DATA/config.json) — load_api_key 顺序与 asr 版一致(env 优先、config 兜底、fail-fast)。
- [ok] A/B 脚本无网络、本地文件对比 — ab_compare.sh 仅 comm/stat/ffprobe;--noproxy/网络 token 零命中。
- [ok] 功能声明 vs 夸大检查(voice cloning 未验证声明) — known_issues.md 第 56 行明确 'Zero-shot voice cloning (9.9 元/音色) … was not verified in this skill's test pass'——SKILL.md 也未把克隆列为核心能力,无夸大。
- [ok] 元数据(license/stars/commit) — 仓库级 MIT、stars=1385、pushed_at=2026-09-09T12:33:29Z;本地 HEAD==pin d5c4678cb5d4fd6acc9c922690df035dbd33d247。
6結論
f7fa276a8ae68d1a…