SyncTrans는 실시간 음성을 번역합니다. 그리고 돈에 관한 실시간 음성은 대체로 정확한 값을 담고 있습니다. 가격, 수량, 할인율처럼요. 이 글은 번역이 유창하고, 자신만만하고, 정작 중요한 숫자에서 틀리는 한 부류의 버그에 관한 이야기입니다. 그리고 1.0.0에서 저희가 출시한, 화려하지는 않은 해결책에 관한 이야기이기도 합니다.
스스로 부호가 뒤집히는 할인
중국어와 일본어에는 모두 할인을 말하는 관용적인 방식이 있고, 둘은 서로 반대 방향으로 셉니다. 중국어는 내는 금액을 셉니다. 七折은 정가의 70%를 낸다는 뜻이므로 30% 할인입니다. 일본어는 빠지는 금액을 셉니다. 같은 제안이 일본어로는 3割引, 즉 10분의 3을 덜어낸다는 표현입니다. 중국어 화자도 일본어 화자도 자기 언어의 관습을 일찍 배우고 나면 다시는 생각하지 않습니다.
번역 모델이 보는 것은 전혀 다른 것입니다. 七折과 割引은 할인 맥락에서 끊임없이 함께 등장하고, 숫자 七은 7에 대응됩니다. 초기 테스트에서 모델들은 七折을 아주 자연스럽게 7割引로 옮겼습니다. 일본어 청자에게는 70% 할인으로 들립니다. 공급자가 “30% 할인해 드릴 수 있습니다”라고 말하면 반대편에서는 “70% 할인해 드릴 수 있습니다”가 나옵니다. 가격 협상에서 이것은 계약 성사와 아주 값비싼 오해 사이의 차이이며, 양쪽 모두 같은 숫자를 들었다고 확신한 채 자리를 뜹니다.
같은 함정, 자릿수를 한 단계 올리면
할인이 가장 날카로운 사례이지만, 같은 구조는 평범한 숫자에서도 나타납니다. 영어는 큰 수를 천 단위로 세고, 중국어는 万(만, 10,000)과 億(억, 100,000,000)으로 셉니다. 12万은 120,000이고, 1.2億은 120,000,000입니다. 단위를 다시 고정하지 않고 숫자만 그대로 옮기는 모델은 12万을 “12,000”으로 만들어 냅니다. 유창하고, 문법에 맞고, 정확히 열 배 틀립니다. 구어 숫자는 상황을 더 악화시킵니다. 음성 인식이 번역기에 넘겨주는 것은 단어의 흐름이고, 자릿수를 결정해 주는 단위는 숫자보다 한 박자 늦게 도착할 수 있기 때문입니다.
모델이 속는 이유
서로 다른 모델에서 왜 이 일이 계속 일어나는지 체감하는 데는 시간이 좀 걸렸습니다. 할인은 방향을 가진 숫자이고, 그 방향은 모델이 옮겨 올 수 있는 어떤 단어가 아니라 숫자 관습 자체에 있습니다. 折을 “할인(off)”에 올바르게 대응시키는 어휘 항목은 존재하지 않습니다. 折은 애초에 '빠지는 양'에 관한 글자가 아니라 '남는 양'에 관한 글자였으니까요. 모델은 수만 번 본 표면 패턴을 재생산할 뿐이고, 값이 뒤집혔는지를 기록해 두는 장부를 안에 갖고 있지 않습니다.
중요한 것은, 이것이 관습의 문제이지 능력의 문제가 아니라는 점을 저희가 확인했다는 것입니다. 저희는 양방향의 할인·큰 수 표현으로 작은 회귀 코퍼스를 만들어, SyncTrans가 출시하는 모든 모델 등급에 대해, 두 온디바이스 스택과 클라우드 엔진 모두에서 실행했습니다. 부호 반전은 모든 크기, 모든 스택에서 나타났습니다. 더 큰 모델은 틀린 숫자를 더 유창하게 표현했습니다. 측정 결과가 이렇게 나오자 결론은 저절로 쓰였습니다. 더 나은 모델을 기다리는 것으로는 해결되지 않으므로, 해결책은 모델 밖에 있어야 했습니다.
모델 뒤의 규칙 레이어
1.0.0의 해결책은 번역기 뒤에 놓여 관습이 붙은 숫자 표현을 감시하는 결정론적 후처리 레이어입니다. 할인 표현이 모호함 없이 파싱되면, 이 레이어는 그것을 언어가 아니라 산수로 취급합니다. 七折은 명시적인 값 — 70%를 낸다, 즉 30% 할인 — 으로 변환된 다음, 목표 언어 자체의 관습으로 다시 표현됩니다. 折은 산수이므로, 산수로 처리하는 것입니다. 万·億 단위로 묶인 숫자도 같은 처리를 받습니다. 자릿수를 단위에서 계산한 다음, 목표 언어의 자릿수 구분으로 렌더링합니다.
이 레이어의 장점은 지루하다는 것입니다. 각 규칙은 정답이 정해진, 단위 테스트 가능한 작은 함수이며, 버그를 증명한 바로 그 코퍼스에 고정되어 있습니다. 규칙이 발동하면 이유를 정확히 말할 수 있습니다. 모델이 즉흥적으로 답하면 그럴 수 없습니다. 유창한 오류가 누군가의 돈이 되는 단 한 부류의 표현에 대해, 저희는 매번 같은 답을 내고 한 줄 한 줄 감사할 수 있는 구성 요소를 원했습니다.
하이브리드의 대가
저희는 트레이드오프를 눈을 뜨고 받아들였고, 그 대가는 실제로 존재합니다. 규칙 레이어는 커버리지만큼만 좋기 때문에, 첫 번째 원칙은 절제입니다. 규칙은 표현이 깔끔하게 파싱될 때만 발동하고, 모호한 것은 모두 모델에 넘깁니다. 추측하는 규칙은 모델이 맞혔을 출력까지 망가뜨리는데, 그것은 원래 버그보다 나쁜 유일한 결과입니다. 두 번째 대가는 유지보수입니다. 관습은 언어 쌍마다 다르고, 저희가 진지하게 다루는 쌍이 늘 때마다 코퍼스도 커져야 하며, 모든 규칙에는 양쪽의 측정이 필요합니다. 그리고 모델은 여전히 나머지 전부를 합니다. 산문, 어조, 컨텍스트까지요. 규칙은 좁고 측정 가능한 한 부류의 실패를 위한 안전장치이며, 두 번째 번역기가 되지 않도록 의도적으로 작게 유지됩니다.
현재 상태
숫자 규칙은 SyncTrans 1.0.0에 포함되어 출시되었고, 코퍼스는 저희 회귀 스위트에서 돌아갑니다. 따라서 앞으로의 모델 업그레이드도 이 코퍼스를 계속 통과해야 합니다. 이 작업은 끝나지 않았습니다. 큰 수의 경계 주변 — 단위가 섞인 경우, 일상 구어로 느슨하게 말해지는 자릿수 — 의 강화는 아직 진행 중이며, 실제 대화가 저희에게 틀리는 새로운 방법을 가르쳐 줄 때마다 코퍼스는 계속 커질 것입니다. SyncTrans에서 뒤집혔거나 줄어든 것처럼 보이는 숫자가 나오면, 알려 주세요. 그런 제보는 코퍼스로 직행합니다.
1.0.0 릴리스에 담긴 더 넓은 이야기는 SyncTrans 1.0까지의 여정을 참조하세요.