Files
mediaplayer/moss/verify.sh
2026-09-11 09:14:51 +08:00

131 lines
4.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#
# 验证 MOSS-Transcribe-Diarize 转写服务:
# 1. 检查 GPU 与服务运行状态
# 2. 用测试音频发起 verbose_json 转写请求,校验响应契约和说话人标签
# 3. (可选)检查 oral-trainer-api 的集成状态
#
# 用法:
# ./verify.sh
# ./verify.sh --file /path/to/speech.wav
# ./verify.sh --url http://127.0.0.1:8001 --model OpenMOSS-Team/MOSS-Transcribe-Diarize
# ./verify.sh --api-url http://127.0.0.1:8000
set -euo pipefail
MOSS_URL="${MOSS_URL:-http://127.0.0.1:8001}"
MOSS_MODEL="${MOSS_MODEL:-OpenMOSS-Team/MOSS-Transcribe-Diarize}"
TEST_FILE=""
API_URL=""
usage() {
sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'
}
while [[ $# -gt 0 ]]; do
case "$1" in
--url) MOSS_URL="$2"; shift 2 ;;
--model) MOSS_MODEL="$2"; shift 2 ;;
--file) TEST_FILE="$2"; shift 2 ;;
--api-url) API_URL="$2"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) echo "未知参数: $1"; usage; exit 1 ;;
esac
done
echo "==> MOSS 地址: $MOSS_URL"
echo "==> 模型: $MOSS_MODEL"
echo "==> 检查 GPU"
if command -v nvidia-smi >/dev/null 2>&1; then
nvidia-smi --query-gpu=name,memory.total,memory.used,driver_version --format=csv,noheader | head -5
else
echo "警告: 未找到 nvidia-smi,无法确认 GPU 状态。"
fi
echo "==> 检查服务健康"
if curl -fsS --max-time 10 "$MOSS_URL/health" > /dev/null 2>&1; then
echo "OK: /health 返回 200"
elif curl -fsS --max-time 10 "$MOSS_URL/healthz" > /dev/null 2>&1; then
echo "OK: /healthz 返回 200"
else
echo "警告: /health 和 /healthz 均不可达,服务可能尚未就绪。"
fi
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
if [[ -n "$TEST_FILE" ]]; then
AUDIO_FILE="$TEST_FILE"
else
echo "==> 生成测试音频(3 秒 440Hz 正弦波)"
if ! command -v ffmpeg >/dev/null 2>&1; then
echo "错误: 未找到 ffmpeg,请安装或用 --file 指定真实语音文件。" >&2
exit 1
fi
AUDIO_FILE="$TMP_DIR/tone.wav"
ffmpeg -hide_banner -loglevel error -f lavfi \
-i "sine=frequency=440:duration=3" -ar 16000 -ac 1 -y "$AUDIO_FILE"
fi
if [[ ! -f "$AUDIO_FILE" ]]; then
echo "错误: 音频文件不存在: $AUDIO_FILE" >&2
exit 1
fi
echo "==> 发起转写请求(verbose_json)"
START_TS="$(date +%s)"
RESPONSE="$(curl -sS --max-time 600 \
-X POST "$MOSS_URL/v1/audio/transcriptions" \
-F "model=$MOSS_MODEL" \
-F "file=@$AUDIO_FILE" \
-F "response_format=verbose_json" \
-F "temperature=0" \
-F "max_new_tokens=65536")"
ELAPSED="$(( $(date +%s) - START_TS ))"
echo "$RESPONSE" | python3 -c '
import json, sys
payload = json.load(sys.stdin)
text = payload.get("text")
segments = payload.get("segments")
assert isinstance(text, str), "响应缺少 text 字段"
assert isinstance(segments, list), "响应缺少 segments 字段(需要 verbose_json)"
speakers = set()
for index, segment in enumerate(segments):
start = segment.get("start")
end = segment.get("end")
speaker = segment.get("speaker")
if not (isinstance(start, (int, float)) and isinstance(end, (int, float)) and end > start >= 0):
raise AssertionError(f"segments[{index}] 缺少合法 start/end")
if speaker:
speakers.add(speaker)
print(f"OK: text={text!r}")
print(f"OK: segments={len(segments)} 条")
if speakers:
print(f"OK: 说话人={sorted(speakers)}")
else:
print("注意: 未见 speaker 字段;单说话人或模型未输出标签(正常弦音无多人对话)。")
'
echo "==> 转写耗时: ${ELAPSED}s"
if [[ -n "$API_URL" ]]; then
echo "==> 检查 API 集成 ($API_URL/healthz)"
curl -sS --max-time 15 "$API_URL/healthz" | python3 -c '
import json, sys
payload = json.load(sys.stdin)
configured = payload.get("moss_configured")
if configured is not True:
raise SystemExit(f"错误: moss_configured={configured!r},请检查 .env 中的 MOSS_TRANSCRIBE_URL")
print("OK: moss_configured=true")
'
fi
echo "全部检查通过。建议再用真实多人对话音频复核说话人分离效果:"
echo " $0 --file /path/to/multi-speaker.wav"