애플리케이션에 필요한 인터페이스를 선택하세요. HTTP 파일 전사, 로컬 MCP 도구, 데스크톱 녹음, 로컬 자막 파이프라인은 지원 모델, 옵션, 반환 필드가 모두 같지 않습니다. 프로세스 안에서 직접 추론하려면 Python SDK(영문)를 사용하세요.
HTTP 서버
다음은 뒤에서 사용할 예제 스크립트까지 포함하는 소스 기반 준비 절차입니다. POSIX 셸에서 새 체크아웃과 가상 환경을 사용하세요. PyPI 패키지만 설치하면 이 저장소의 예제 스크립트가 함께 배치되지는 않습니다.
git clone https://github.com/modelscope/FunASR.git FunASR-agent
cd FunASR-agent
git checkout --detach e19029adca384a06a2f60bd8c18cb98f1a0499aa
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
python -m pip install fastapi uvicorn python-multipart
python -m pip check
이 절차는 소스 리비전만 고정하며 모든 의존 패키지와 모델 가중치를 고정하지는 않습니다.
설치 가이드(영문)에 따라 CPU/GPU 환경을 준비하고,
실제 패키지 및 모델 버전을 기록한 뒤 대상 모델로 요청을 검증하세요.
pip check만으로 CUDA, 오디오 디코더, 새 환경 설치가 정상임을 확인할 수는 없습니다.
준비된 환경에서 다음 명령 중 하나만 실행하세요. CPU 예제는 SenseVoice를 명시적으로 선택합니다. CUDA 대안에는 작동하는 GPU 환경이 필요합니다. 서버 터미널을 유지하고, 클라이언트는 별도로 준비한 다른 터미널에서 실행하세요.
funasr-server --host 127.0.0.1 --device cpu --model sensevoice --port 8000
# Alternative: stop the CPU server before using the same port.
funasr-server --host 127.0.0.1 --device cuda --model sensevoice --port 8000
curl -fsS http://localhost:8000/health
curl -fsS http://localhost:8000/v1/models
- 파일 업로드에는
/v1/audio/transcriptions를 사용합니다. - 실행 중인 서비스의 스키마는
/openapi.json에 있습니다. - Swagger UI는
/docs에 있습니다. 이 경로는 FunASR 웹사이트의 문서 디렉터리가 아닙니다.
상태 확인이나 모델 목록 응답이 성공해도 대상 모델의 실제 전사가 성공했다는 뜻은 아닙니다.
패키지의 funasr-server와 예제 HTTP 서버(영문)는
기본값, 별칭, 응답 스키마가 다릅니다. 시작할 때뿐 아니라 요청에도 model을 지정하세요.
paraformer-en은 예제 서버의 별칭이며 패키지 서버의 내장 별칭이 아닙니다.
사용자 지정 모델은 적절한 --hub와 --model-path로 설정하고 요청에는 model="custom"을 사용하세요.
임의의 모델 ID가 자동으로 --model의 내장 별칭이 되는 것은 아닙니다.
SenseVoice의 HTTP 표시 텍스트에서는 리치 태그가 제거됩니다. 이 서비스는 감정이나 이벤트를 전용 필드로 반환하는 API가 아닙니다. 기본 Fun-ASR-Nano는 중국어·영어·일본어 및 중국어 방언·지역 억양의 평가 경로이고, 31개 언어를 다루는 Fun-ASR-MLT-Nano는 별도 checkpoint입니다. 기본 Nano의 범위가 한국어 지원을 뜻하지 않으며, HTTP 인터페이스만으로 타임스탬프를 보장할 수도 없습니다. 모델 선택과 배포 방식에서 실제 경로를 확인하세요.
MOSS-Transcribe-Diarize(영문)는 OpenMOSS가 제공하는 제3자 모델이며 별도의 배포 요건이 있습니다. 네이티브 화자 라벨은 녹음 내 익명 라벨이지 실제 인물의 신원이 아닙니다. 외부 VAD나 외부 화자 모델이 필요하지 않으므로 해당 단계를 추가하지 마세요. 모든 클라이언트가 모델의 전체 출력을 표시한다고 가정해서도 안 됩니다.
로컬 서버는 아래 SDK의 임시 API 키를 인증하지 않습니다. 네트워크에 공개하기 전에 보안 가이드(영문)에 따라 TLS, 인증, 업로드 크기 제한, 요청 속도 제한을 추가하세요. CORS는 인증이 아닙니다.
SDK와 curl
클라이언트 환경에 별도의 OpenAI HTTP 클라이언트를 설치합니다.
python -m pip install openai
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="local-development")
with open("meeting.wav", "rb") as audio:
result = client.audio.transcriptions.create(
model="sensevoice",
file=audio,
response_format="verbose_json",
)
print(result.text)
for segment in getattr(result, "segments", []):
print(segment)
curl -fsS http://localhost:8000/v1/audio/transcriptions \
-F file=@audio.wav \
-F model=sensevoice \
-F response_format=verbose_json
verbose_json은 응답 형식만 선택합니다. 화자 분리를 켜거나 리치 태그를 복구하지 않으며,
단어 단위 시각이나 정렬도 보장하지 않습니다. 예제 서버는 기존 sentence_info를 segments로
옮기고, 해당 정보가 없으면 빈 목록을 반환합니다. 패키지 서버는 대략적인 대체 구간을 만들 수 있습니다.
두 서버 모두 segment 시각을 초 단위로 반환하지만 duration 필드의 의미는 다릅니다.
시각을 사용하기 전에 클라이언트 응답 계약(영문)을 확인하세요.
json과 text는 더 단순한 응답 형식입니다.
spk=true 화자 처리는 패키지 API에 속하며 예제 서버의 요청 스키마에는 없습니다.
화자 라벨과 신원 식별의 차이(영문)도 참고하세요.
워크플로 연동
Dify/n8n 등의 HTTP 노드에서 전사 엔드포인트로 POST multipart 요청을 보냅니다.
바이너리 파일 필드 이름은 file이고 텍스트 필드는 model과 response_format입니다.
file 필드에 오디오 URL을 넣는 것은 오디오 바이트를 업로드하는 것과 다릅니다.
컨테이너 안의 localhost는 FunASR 호스트가 아니라 해당 컨테이너 자신을 가리킵니다.
의도한 게이트웨이를 통해 접근 가능한 서비스 주소를 설정하세요.
- Dify, n8n, webhook worker(영문): 요청 연결 예제.
- JavaScript / TypeScript(영문): SDK 및 multipart 클라이언트.
- Postman(영문)과 스모크 테스트: 배포된 엔드포인트 확인.
- Gradio(영문): 브라우저 업로드 및 마이크 입력.
- OpenAPI(영문): 저장소 예제 스키마와 실행 중인 패키지 서비스 스키마의 차이.
이 요청 및 응답 범위에 맞춰 호스트 프레임워크에 전사 도구를 등록하세요. URL worker 예제는 완전한 보안 기능을 갖춘 다운로더가 아닙니다. 신뢰할 수 없는 URL을 받기 전에 목적지 허용 목록, 사설 네트워크 접근 차단, 리디렉션 검증, 크기 제한과 타임아웃을 추가하세요. 워크플로 필드 표가 두 서버 모두에 그대로 적용된다고 가정하지 말고 위의 응답 계약을 사용하세요. 이 예제는 모든 프레임워크 버전의 연동이 검증되었다는 증거나 임의의 URL이 안전하다는 보장이 아닙니다.
MCP 서버
준비된 저장소 루트와 환경에서 실행합니다.
python examples/mcp_server/funasr_mcp.py
전사 전에 설치 가이드에 따라 PyTorch와 호환되는 오디오 특징 추출 백엔드를 준비하세요. 툴킷 설치나 MCP 핸드셰이크 성공만으로 모델 실행이 검증되지는 않습니다. 이 스크립트에는 추가 MCP SDK 패키지가 필요하지 않습니다. MCP 클라이언트가 HTTP가 아닌 stdio로 스크립트를 시작합니다. 준비된 Python 환경과 체크아웃의 절대 경로를 설정하세요.
{
"mcpServers": {
"funasr": {
"command": "/path/to/FunASR-agent/.venv/bin/python",
"args": ["/path/to/FunASR-agent/examples/mcp_server/funasr_mcp.py"],
"env": {
"FUNASR_DEVICE": "cpu",
"FUNASR_MODEL": "iic/SenseVoiceSmall"
}
}
}
}
transcribe_audio는 서버에서 볼 수 있는 기존 로컬 audio_path를 받습니다.
컨테이너에 읽기 전용으로 마운트된 경로도 사용할 수 있지만 URL이나 실시간 스트림은 받지 않습니다.
첫 호출에서 가중치를 다운로드하고 로드할 수 있습니다.
언어 힌트는 auto, zh, yue, en, ja, ko입니다.
FUNASR_MODEL을 바꾸어도 도구 스키마가 바뀌지 않으며 다른 모델이 해당 VAD 경로와 호환된다는 보장도 없습니다.
결과는 MCP content의 type=text로 형식화되며 선택적으로 구간 정보를 포함합니다.
HTTP 응답 객체가 아닙니다. 최상위 전사 텍스트에서 리치 태그를 제거하지만,
선택적 구간 텍스트는 모델 출력에서 복사합니다.
FUNASR_DEVICE의 기본값은 cpu, FUNASR_MODEL의 기본값은 iic/SenseVoiceSmall입니다.
MCP 소스와 컨테이너 설정에서 클라이언트 설정과 마운트 방법을 확인하세요.
어시스턴트와 서버가 접근할 수 있는 파일을 제한해야 합니다. 로컬 도구 자체가 파일 시스템 권한 경계는 아닙니다.
데스크톱 음성 입력
HTTP 서버를 실행한 상태에서 준비된 체크아웃의 다른 터미널을 사용합니다.
python -m pip install sounddevice numpy pyperclip openai pynput
python examples/voice_input/funasr_input.py --server http://localhost:8000/v1 --model sensevoice
스크립트는 녹음을 시작하거나 중지하고, WAV를 HTTP 서비스에 업로드한 뒤 전사 텍스트를 복사합니다.
마이크 권한과 오디오 장치 지원이 필요합니다. macOS에서는 손쉬운 사용 권한도 필요할 수 있으며,
Linux의 자동 붙여넣기는 xdotool을 사용합니다. 클립보드와 붙여넣기 동작은 데스크톱 세션에 따라 달라집니다.
현재 --lang 옵션은 파싱되지만 전사 요청에 전달되지 않아 이 경로에서 유효한 언어 제어 옵션이 아닙니다.
원격 --server를 지정하면 녹음이 해당 엔드포인트로 전송됩니다.
항상 완전히 오프라인이거나 오디오가 기기를 벗어나지 않는다는 보장, 고정 지연 시간 보장은 없습니다.
배포 전에 설정 옵션과
구현을 확인하세요.
자막 생성
이것은 로컬 AutoModel 파이프라인이며 HTTP나 MCP 클라이언트가 아닙니다.
준비된 체크아웃에서 로컬 입력 파일과 적절한 추론 환경을 사용합니다.
python examples/subtitle/generate_subtitle.py video.mp4
python examples/subtitle/generate_subtitle.py meeting.wav --spk
python examples/subtitle/generate_subtitle.py podcast.mp3 --format vtt
python examples/subtitle/generate_subtitle.py audio.wav --device cpu
기본 장치는 CUDA이고 마지막 명령은 CPU를 명시적으로 선택합니다.
기본 모델은 SenseVoiceSmall이며 VAD와 문장부호 모델을 함께 사용합니다.
이 고정 파이프라인은 임의의 모델에 적용할 수 있는 범용 실행법이 아닙니다.
--spk는 CAM++ 익명 화자 라벨을 추가하지만 실제 신원을 확인하지 않습니다.
--format은 SRT/VTT를 선택하고 --output은 출력 경로를 지정합니다.
기존 출력 파일은 덮어씁니다. 이전 자막을 보존하려면 다른 경로를 지정하세요.
--lang은 auto가 아닌 언어 힌트를 추론에 전달합니다.
--max-single-segment-time의 단위는 밀리초이며 현재 기본값은 60000입니다.
--segment-mode readable은 인식 텍스트나 문장부호를 다시 쓰지 않고 표시용 자막을 묶습니다.
sentence는 모델의 원래 문장 구분을 유지합니다. 두 모드 모두 문장부호 오류를 고치거나 음소 경계를 보장하지 않습니다.
실제 타임스탬프가 있는지 확인하고 원본 오디오와 재생을 대조하세요.
시간 정보가 없으면 길이가 0인 (0, 0) 구간으로 대체될 수 있으며, 이는 유효성이 검증된 자막이 아닙니다.
입력 디코딩, 모델 및 의존 패키지 로딩, GPU 용량은 환경별로 검증해야 합니다.
출력 해석은 자막 옵션(영문)과
화자 가이드(영문)를 참고하세요.