1487 words
7 minutes
Whisper V3 Turbo - Cohere Transcribe 전환기

일본어 컨텐츠덕질를 자주 접하게 되면서 여러모로 음성-텍스트 전사를 필요로 하게 되었다.

그러나 일본어, 한국어 등 화자 수가 적은 언어일수록 모델마다 성능편차도 심할뿐더러 정확도 또한 낮아진다는 문제가 있다.

한동안 여러가지 STT 모델을 사용해보며 정착했던 두 가지 모델과 그 전환기를 작성해본다.

전문적이지 않을 뿐더러 파인튜닝을 하지 않았기에 차이가 있을 수 있다.


처음엔 당연히 Whisper를 선택했고, 한동안은 문제없이 썼다.

그런데 쓰면 쓸수록 특정 패턴의 오류가 반복됐다.


Whisper V3 Turbo를 선택한 이유#

Whisper Large V3가 나왔을 때 성능은 훌륭했지만 속도가 문제였다. 그 다음 나온 V3 Turbo는 Large V3를 증류(distillation)해서 만든 약 800M 파라미터짜리 모델인데, 속도와 정확도의 균형이 꽤 좋았다.

Apple Silicon 맥에서 MPS 가속을 쓰면 실시간 대비 10배 이상 나왔고, 다국어 지원도 폭넓었다. 커뮤니티도 크고 faster-whisper 같은 최적화 래퍼도 있어서 실용적인 선택이었다.

일본어 품질도 처음엔 나쁘지 않았다. 일상 대화나 팟캐스트 수준에서는 충분했다.


실제로 겪은 문제들#

문제는 음원의 성격이 조금만 달라지면 생겼다.

반복 루프#

가장 심했던 건 같은 단어나 문장이 무한 반복되는 현상이다.

ありがとうございます。ありがとうございます。ありがとうございます。ありがとうございます。

이런 식으로 출력이 도배되는 경우가 종종 있었다. 특히 배경음악이 깔린 구간이나, 발화 사이 짧은 침묵이 있는 구간에서 자주 터졌다. Whisper가 “적을 게 없으니 그럴싸한 것을 채운다”는 느낌이었다.

내용 소멸#

반대 방향의 문제도 있었다. 분명히 말을 하고 있는데 그 구간이 통째로 날아가는 것이다. 30초 단위로 오디오를 잘라서 처리하는 Whisper의 특성상, 청크 경계에 걸친 발화가 잘려나가는 경우가 꽤 있었다.

일본어는 조사와 어미가 단어 뒤에 붙는 구조라, 경계에서 잘리면 의미 단위 자체가 깨져버린다. 食べ 뒤에 오는 ました가 다음 청크로 넘어가면서 두 청크 모두 해당 단어를 무시해버리는 식이다.


Whisper에서 개입할 방법이 제한적인 이유#

반복 루프 문제를 해결하려고 파라미터를 건드려봤지만 쉽지 않았다.

Whisper는 OpenAI가 독자적으로 구현한 디코딩 파이프라인을 쓴다. HuggingFace의 model.generate()를 직접 통과하지 않아서, repetition_penaltyno_repeat_ngram_size 같은 표준 생성 파라미터를 주입하기가 까다롭다. faster-whisper 같은 래퍼를 써도 이 부분은 노출이 안 되어 있거나 제한적이다.

결국 파라미터로 해결하기보다 전처리에서 무음 구간을 잘라낸다거나, 후처리에서 중복을 제거하는 방식으로 우회해야 했는데, 근본적인 해결이 아니라 계속 손이 갔다.


Cohere Transcribe로의 전환#

반복 억제 파라미터가 실제로 먹힌다#

REPETITION_PENALTY = 1.3
NO_REPEAT_NGRAM = 4

repetition_penalty=1.3은 이미 생성한 토큰이 다시 나올 확률에 패널티를 준다. 값이 클수록 반복을 더 강하게 억제하는데, 1.3은 자연스러운 반복 표현(문법적으로 같은 단어가 연속되는 경우)은 허용하면서 루프는 잡아주는 균형점이다.

no_repeat_ngram_size=4는 동일한 4-gram이 두 번 나오지 못하게 막는다. 앞의 두 설정이 함께 작동하면 Whisper에서 자주 보이던 반복 루프가 현저히 줄어들었다.

청크 경계 처리#

긴 오디오는 메모리 제약 때문에 청크로 나눠서 처리해야 한다. Whisper는 청크를 독립적으로 디코딩하기 때문에 경계 맥락이 전혀 없다. 반면 이 구현에서는 청크별 출력 토큰을 패딩 정렬해서 합산한 뒤 한 번에 디코딩한다.

max_len = max(p.shape[1] for p in pieces)
# 각 청크 출력을 최대 길이에 맞춰 패딩 후 결합

청크 경계에서 내용이 사라지는 문제가 이 방식으로 상당히 개선됐다.

구두점 파라미터 분리#

processor(..., punctuation=punctuation)

구두점 출력 여부를 파라미터로 직접 제어할 수 있다. 이후 자동화 처리를 위해 구두점 없는 순수 텍스트가 필요할 때와, 가독성을 위해 구두점이 필요할 때를 깔끔하게 나눌 수 있어서 후처리가 훨씬 단순해졌다.


문제점#

메모리 사용량이 높다. Apple Silicon MPS에서 float16이 불안정해서 float32를 써야 한다. Whisper가 float16으로 가볍게 돌던 것과 비교하면 메모리 부담이 확실히 크다.

최적화 래퍼가 없다. faster-whisperwhisper.cpp 같은 커뮤니티 최적화 도구가 Whisper에는 많이 쌓여 있지만, Cohere 모델은 아직 그 수준이 아니다. 속도만 보면 Whisper가 유리한 상황이 있다.


정리#

항목Whisper V3 TurboCohere Transcribe
반복 루프 억제파라미터 개입 어려움repetition_penalty 직접 작동
청크 경계 처리독립 디코딩토큰 합산 후 디코딩
MPS 메모리float16 가능float32 강제
커뮤니티/래퍼풍부초기 단계
라이선스MITApache 2.0
Whisper V3 Turbo - Cohere Transcribe 전환기
https://ahri2nd.xyz/posts/whisper-to-cohere-transcribe/
Author
Tsukimori Ahri
Published at
2026-06-05
License
CC BY-NC-SA 4.0