프렌들리AI, 업스테이지, 채널지금 글로벌 AI 최전선 이야기가 궁금하다면?대표가 말하는 글로벌 AI의 최전선자세히 보기

Voice Turn Detection 모델 개발기

VoiceALF가 “입을 뗄 타이밍”를 배우게 하려면

Bard • KR Office Applied AI Engineer

  • AI

전화는 생각보다 고도화된 의사소통이다

채널톡은 VoiceALF를 통해 전화 상담의 여러 문제를 AI로 풀고 있습니다. 처음에는 저희도 ALF에 입과 귀를 달아주면 자연스럽게 통화할 수 있을 거라고 생각했습니다. 그런데 그렇게 만든 AI는 정말로 “말하고 듣는 것만” 할 수 있었고, 전화와는 조금 달랐습니다.

전화 상담에는 두 가지 능력이 함께 필요합니다.

  • 무엇을 말할까? 고객의 요구를 이해하고, 회사의 정책에 맞는 답을 찾는 능력

  • 언제 말할까? 고객이 말을 마쳤는지, 잠깐 생각하는 중인지 알아차리는 능력

답변이 아무리 정확해도 주문 도중에 끼어들거나, 다 말했는데 한참 기다리게 한다면 대화가 어색해집니다. 사람에게는 익숙한 이 타이밍을 AI에게도 가르쳐야 했습니다.

오늘은 VoiceALF가 말해야 할 때와 기다려야 할 때를 구분하게 된 과정인 Turn Detection(TD) 개발기를 소개합니다.

Turn Detection: 전화에는 빠질 수 없는 작은 판단

고객의 침묵 ≠ AI의 발화 타이밍

“말소리가 멈추면 대답하면 되는 것 아닌가요?” 가장 먼저 떠올릴 수 있는 방법입니다. 하지만 같은 침묵도 대화 속에서는 의미가 꽤 다릅니다.

  • 답해도 되는 순간: “사용 기간이 2년이 안 돼서 A/S 신청하려고요.”

  • 끝맺음이 흐려도 답할 수 있는 순간: “이게 쓰던 게 고장이 나서요… 한 2년인가 썼는데…”

  • 아직 기다려야 하는 순간: “제품 기기 번호요? 잠시만요.” 또는 “핸드폰 번호 공 일 공에…”

사람은 문장뿐 아니라 억양과 머뭇거림을 함께 듣고 그 차이를 알아챕니다. AI에게 “일정 시간 조용하면 답하기”라는 규칙만 주면 어떨까요? 시간을 짧게 잡으면 고객의 말을 자르고, 길게 잡으면 이미 끝난 말 뒤에도 침묵이 붙습니다.

TD는 이 갈림길에서 “지금 답할까, 조금 더 기다릴까?”를 고르는 역할을 합니다. 고객이 잠시 말을 멈출 때마다, 그때까지 들은 음성을 바탕으로 판단합니다.

턴 기반 대화에서 전송 버튼이 없다면?

보통의 STT-LLM-TTS 방식의 Cascading Voice Agent 시스템 구조도. TD 모델은 응답 시간 지연을 최소화하기 위해 STT와 병렬로, VAD 직후에 동작.

채팅에는 전송 버튼이 있습니다. 사용자가 메시지를 보내면 AI는 그때 답하면 되고, 99.9%의 LLM은 이렇게 주고받는 턴에 기반해 대화하도록 설계되어 있습니다. 그러나 전화에는 이 버튼이 없습니다. 전화를 받는 순간부터 양쪽의 소리가 계속 들어오고, 누가 말할 차례인지도 시시각각 달라집니다.

VoiceALF 안에서는 다음 작업이 함께 돌아갑니다.

  1. 말을 받아 적기: 음성 인식(STT)이 고객의 말을 계속 텍스트로 바꿉니다.

  2. 잠깐의 멈춤 찾기: 음성 감지(VAD)가 고객의 말소리가 멈춘 순간을 찾습니다.

  3. 답할 타이밍 정하기: TD가 그 순간까지의 음성을 듣고, 고객의 말을 하나의 메시지로 확정해도 되는지 판단합니다.

답해도 된다면 지금까지의 전사를 AI에게 전달하고, 만들어진 답을 음성 합성(TTS)으로 들려줍니다. 더 기다려야 한다면 다음 말을 이어서 받습니다. 너무 오래 기다리지 않도록 최대 대기 시간도 둡니다.

즉 TD는 계속 받아 적히는 고객의 말 옆에서 전송 버튼을 눌러주는 역할입니다. 이 버튼을 누를지 고민하는 동안에도 음성 인식은 계속됩니다.

고객 상담 전화에 맞는 기준부터

물론 비슷한 고민을 하는 팀은 많았습니다. TEN Turn Detection, Pipecat Smart Turn처럼 공개된 모델도 있습니다. 다만 일상 대화와 전화 상담은 말투도, 음질도, 잠시 기다려야 하는 상황도 다릅니다. 공개 모델의 점수만으로 우리 전화에서의 동작을 알기는 어려웠습니다.

그래서 저희는 채널톡의 전화에서 어떤 순간에 답하고, 어떤 순간에 기다려야 하는지부터 정했습니다. 모델을 비교할 공개 시험은 뒤에서 다루고, 먼저 실제 상담에서 학습과 평가의 기준을 만들기로 했습니다.

[번외] 음성 AI 분야 자체의 마이너함을 깨달았던 에피소드

약간 다른 얘기지만, 음성 도메인 자체가 생각보다 LLM 같은 메인스트림에 비해서는 관심이 덜하구나 하고 느꼈던 사례도 있습니다.

보통 트랜스포머 계열 모델은 서빙할 때 vLLM이라는 오픈소스 프레임워크를 자주 사용합니다. AI를 하는 사람이라면 모를 수 없는 유명 프레임워크이고, 거기에 저희가 사용한 모델은 Google이 발표한 Gemma4, 아주 유명한 오픈 웨이트 모델 패밀리입니다.

그러나 그 두 조합으로 오디오를 받도록 서빙했을 때, 배치 처리에서 길이가 서로 다른 오디오 파일을 동시에 처리하면 엔진이 죽는 아주 기본적인 기능에 치명적인 버그가 있었습니다. 다시 말해, Gemma4 모델이 발표된 지 5개월 동안 vLLM에서 오디오 처리가 제대로 되지 않았음에도 커뮤니티에서 높은 우선순위로 이 문제를 바라보지 않았다는 것입니다.

다행히 저희 팀에서 빠르게 PR을 올려 수정하긴 했지만, 음성 분야에 아직 기여할 부분들이 많이 남아있겠다고 느낀 사건이었습니다.

채널톡의 모든 전화 녹음에 “턴” 라벨 붙이기

세 가지 라벨: 실제 발화 907개로 정답지 만들기

첫 작업은 실제 상담을 듣는 것이었습니다. 약 1,000개의 발화를 골라 직접 듣고 표시할 수 있는 내부 도구를 만들었고, 잡음이나 테스트 통화 등을 제외한 907개를 정답지로 남겼습니다.

처음에는 “끝났다 / 아직이다” 두 가지면 충분할 줄 알았습니다. 그런데 “네네”, “아 그렇군요”가 문제였습니다. 짧은 말은 끝났지만, 상대에게 답을 요구하는 것인지 그저 잘 듣고 있다는 표시인지 구분해야 했습니다.

그래서 정답을 세 가지로 나눴습니다.

  • 말이 끝남 (416개): 상대가 답해도 되는 순간

  • 아직 말하는 중 (431개): 말을 잇거나 생각할 시간을 줘야 하는 순간

  • 맞장구 (60개): 상대의 말을 듣고 있다는 짧은 반응

맞장구를 따로 남기니 애매한 사례를 논의하기 쉬워졌습니다. 이후에는 같은 정답지로 자동 라벨과 모델의 판단을 점검하고 맞장구를 제품에서 어떻게 처리할지도 비교할 수 있었습니다.

수십만 개의 발화에 정답을 붙이려면

VAD 모듈의 Voice Activity 종료 판단 시점을 기준으로 양쪽의 오디오 특성을 보는 라벨러의 구조. TD 모델과 다르게 미래 시점의 음성까지 활용해 판단을 수행한다.

정답의 기준은 생겼지만 사람이 직접 들어야 할 발화는 약 90만 개였습니다. 이를 학습에 활용하려면 라벨을 붙이는 과정부터 자동화해야 했습니다.

저희는 고객과 상담사의 말이 이어지는 모습을 살폈습니다. 누가 얼마나 말했는지, 서로 겹쳐 말했는지, 고객의 말이 멈춘 뒤 어느 쪽이 다시 말했는지가 단서가 됐습니다. 이런 단서들을 조합해 사람이 붙인 세 가지 라벨을 재현하는 자동 라벨러를 만들었습니다.

자동 라벨러에는 한 가지 유리한 조건이 있습니다. 통화가 끝난 뒤라서 다음에 무슨 일이 일어났는지까지 볼 수 있다는 것입니다. 스포츠 경기의 비디오 판독처럼 앞뒤 상황을 돌아보고 정답을 붙일 수 있습니다. 실시간 TD는 아직 일어나지 않은 다음 대화를 볼 수 없으니, 두 도구의 역할은 다릅니다.

이렇게 만든 라벨을 사람의 정답지와 대조해 점검하고, 대규모 통화를 모델이 배울 수 있는 데이터로 바꿨습니다. 사람이 모든 발화를 듣지 않아도 사람이 정한 기준을 학습에 반영할 수 있는 길이 생겼습니다.

실시간 추론이 되는 TD 모델 학습시키기

음성을 직접 듣고, 말의 흐름을 이해하는 모델

오디오 인코더 & LLM으로 구성된 원래의 Gemma4-2B 모델(a)과 Text Generation Head를 Classification head로 교체한 Turn Detection 모델(b)의 구조 비교.

오디오 인코더 & LLM으로 구성된 원래의 Gemma4-2B 모델(a)과 Text Generation Head를 Classification head로 교체한 Turn Detection 모델(b)의 구조 비교

이제 실제 전화에서 판단할 모델을 만들 차례입니다. 저희는 Google의 음성을 이해하는 언어 모델 Gemma4-2B를 바탕으로, 음성을 듣고 짧은 판단을 내리는 일에 집중하도록 구조를 바꿨습니다.

원래 모델은 긴 답변을 글로 만드는 기능을 갖고 있습니다. TD에는 그 기능을 대신해 몇 가지 선택지의 점수를 바로 내는 출력부를 붙였습니다. 말을 이해하는 능력은 활용하면서, 답변을 한 글자씩 생성할 필요는 없앤 것입니다.

입력도 전화에서 사용할 수 있는 정보에 맞췄습니다. 모델은 판단 시점까지의 고객 음성만 듣습니다. 받아 적은 문장을 기다리지 않으므로 전사 지연이나 오인식에 의존하지 않고, 억양과 머뭇거림도 직접 참고할 수 있습니다.

자동으로 라벨을 붙인 데이터에서 학습용 발화를 구성하고, 이 모델이 전화의 짧은 멈춤마다 판단하도록 학습했습니다.

세 개의 라벨, 하나의 목적

맞장구를 어떻게 가르치느냐에 따라 달라지는 응답 성향. 세 가지 학습 방식의 끝남/이어짐 구분 성능과 맞장구를 답하기로 분류한 비율을 두 패널로 비교. 턴 구분 성능은 별도 평가 421건, 맞장구 반응은 60건 기준이며 실제 통화의 말 끊김 비율과는 다름.

정답지는 세 종류지만, 제품에서 내려야 할 결정은 간단합니다. 지금 전송 버튼을 누를까요, 조금 더 기다릴까요?

맞장구를 다루는 방법도 이 결정에 맞춰 실험했습니다.

  • 맞장구를 별도 종류로 학습하기

  • 맞장구를 “답하기” 쪽에 포함하기

  • 맞장구를 “기다리기” 쪽에 포함하기

같은 음성에 붙이는 학습 라벨만 달리해도 모델의 응답 성향이 달라졌습니다. 그래서 끝난 말과 이어질 말을 잘 구분하는지에 더해, 맞장구에 얼마나 적극적으로 반응하는지도 함께 살폈습니다. 이 실험을 통해 데이터에 붙인 이름이 실제 전화에서의 행동으로 이어진다는 것을 확인했습니다.

VoiceALF의 Turn Detector

100ms대의 빠른 판단, 공개 평가에서도 확인한 구분 능력

전화에 들어갈 모델은 빠르게 판단해야 합니다. 저희 TD의 모델 계산 시간은 중앙값 약 101ms, 음성 전처리까지 포함해도 약 116ms였습니다. 두 후보 모두 전처리를 포함해 요청 100건 중 약 95건을 170ms 안에 처리했습니다. 전화의 짧은 멈춤마다 판단할 수 있는 속도입니다.

RTX A6000에서 음성을 한 건씩 실제 처리한 모델 추론 시간(좌)과 전처리 포함 시간(우)의 누적 분포. 사용한 오디오 길이 중앙값은 6.9초였으며, 가로축은 전처리와 모델 계산에 걸린 시간(ms), 세로축은 해당 시간 안에 처리된 요청 비율.

정확하게 구분하는 능력은 공개 벤치마크인 EoT-Bench로 확인했습니다. 한국어 대화 속 759번의 멈춤을 대상으로, 말이 끝난 순간과 중간에 잠깐 쉰 순간을 구분하는 평가입니다.

저희 두 후보는 AUC 0.952와 0.939를 기록했습니다. AUC는 끝난 말에 더 높은 점수를 주는 능력을 나타내며, 1에 가까울수록 잘 구분한다는 뜻입니다. 두 후보 모두 이번 비교에서 LiveKit v1-mini(0.919), SmartTurn v3.2(0.842), ultraVAD(0.803)보다 높은 점수를 보였습니다.

LiveKit의 EoT-Bench 한국어 구분 성능 비교.

빠른 추론과 함께 전화에서는 얼마나 기다린 뒤 답할지도 설정합니다. EoT-Bench에서 중간 멈춤을 잘못 끊는 비율을 5% 이하로 맞췄을 때 평균 응답 결정 대기 시간(delay)은 약 0.58초였습니다. 이는 모델 계산 시간을 제외한 대기 정책의 지표로, 앞서 측정한 100ms대 추론 시간과 구분됩니다.

이렇게 고객 음성만으로 빠르게 판단하면서, 공개된 한국어 대화에서도 여러 비교 모델을 앞서는 구분 성능을 확보했습니다. 다음은 이 판단을 실제 주문 전화에 연결할 차례였습니다.

사내 카페에서 테스트한 9,500여 번의 분류

첫 적용 무대는 직원들이 사용하는 사내 카페 전화 채널이었습니다. 2026년 8월 24일부터 9월 7일까지 대시보드에 기록된 판단 요청은 9,521건입니다. 한 통화에서도 여러 번 판단하므로, 통화 수와는 다릅니다.

이후 발화 여부와 대조할 수 있었던 8,210건에서는 다음과 같이 동작했습니다.

  • 지금 답하기: 6,199건(75.5%)

  • 조금 더 기다리기: 2,011건(24.5%)

특히 기다리기를 선택한 2,011건 중 1,750건(87.0%)에서는 1.5초 안에 발화가 이어졌습니다. 사내 전화에서 기다리기 기능이 실제로 쓰였고, 그 뒤 말이 이어지는 상황도 확인한 것입니다.

물론 다음 발화의 여부만으로 대화 품질 전체를 평가할 수는 없습니다. 이 수치는 적용 전후의 개선율이 아닌 운영 관측값입니다. 대신 저희에게는 모델의 판단을 실제 전화 흐름과 연결해 보고, 너무 빨랐거나 더 기다릴 필요가 있었던 사례를 찾아볼 기반이 생겼습니다.

모델을 만들고 시험하는 데서 한 걸음 더 나아가, 실제 주문 전화의 타이밍을 맡기고 그 결과로 다음 개선점을 찾는 단계에 들어섰습니다.

대화는 타이밍까지

처음의 카페 주문으로 돌아가 보겠습니다. “아이스 아메리카노 한 잔이랑, 잠시만요…” 다음에는 추가 주문이 이어질 수 있습니다. 좋은 전화 AI라면 이 짧은 멈춤에도 귀를 기울여야 합니다.

이번 개발을 통해 저희는 사람이 판단한 기준을 학습 데이터로 확장하고, 100ms대에 판단하는 TD를 만들어 사내 주문 전화에 연결했습니다. VoiceALF에 말을 이해하는 능력과 함께 답할 때와 기다릴 때를 고르는 능력을 더한 것입니다.

다음으로는 주변 소음이 섞인 상황에서도 이 판단을 더 안정적으로 다듬으려 합니다. 주문을 생각하는 시간에는 기다리고, 말을 마치면 자연스럽게 답하는 전화. VoiceALF가 만들어갈 상담 경험입니다.

"무엇"을 말할지 뿐만 아니라, "언제" 말할지도 대화의 일부이기 때문입니다.

We Make a Future Classic Product