SyncTrans traduce habla en directo, y el habla en directo sobre dinero suele ser exacta: un precio, una cantidad, un descuento. Este artículo trata de una clase de error en la que la traducción es fluida, segura de sí misma y está equivocada en la cifra que importa — y de la solución poco glamurosa que publicamos para ello en la 1.0.0.
El descuento que invierte su propio signo
El chino y el japonés tienen formas idiomáticas de expresar un descuento, y cuentan en direcciones opuestas. El chino cuenta lo que pagas: 七折 significa que pagas el 70% del precio de lista, es decir, un 30% de descuento. El japonés cuenta lo que se quita: la misma oferta es 3割引 — tres décimas que se descuentan. Cada hablante de chino y cada hablante de japonés aprende su propia convención muy pronto y nunca vuelve a pensar en ella.
Un modelo de traducción ve algo completamente distinto: 七折 y 割引 aparecen juntos constantemente en contextos de descuento, y el dígito 七 corresponde al 7. En nuestras primeras pruebas, los modelos traducían 七折 tan tranquilamente como 7割引 — que un oyente japonés entiende como un 70% de descuento. Un proveedor que dice “puedo hacerte un 30% de descuento” sale por el otro extremo como “puedo hacerte un 70% de descuento”. En una conversación de precios, eso es la diferencia entre cerrar un trato y un malentendido muy caro, y ambas partes se marchan convencidas de haber oído la misma cifra.
La misma trampa, un orden de magnitud más arriba
Los descuentos son el caso más afilado, pero la misma estructura subyacente aparece también en los números a secas. El español, como el inglés, agrupa los números grandes de mil en mil; el chino los cuenta en 万 (diez mil) y 億 (cien millones). 12万 es 120.000. 1,2億 es 120.000.000. Un modelo que traslada los dígitos sin reajustar la unidad produce “12.000” para 12万 — fluido, gramatical y equivocado en un factor de diez. Los números hablados lo empeoran, porque el reconocimiento entrega al traductor un flujo de palabras y la unidad que desambigua la magnitud puede llegar una respiración entera después de los dígitos.
Por qué el modelo cae en la trampa
Nos costó un tiempo interiorizar por qué esto seguía ocurriendo en modelos distintos. Un descuento es un número con una dirección, y la dirección vive en la convención numérica, no en ninguna palabra que el modelo pueda trasladar. No existe una entrada de vocabulario que asigne 折 a “de descuento” correctamente, porque 折 nunca trató de lo que se quita — siempre trató de lo que se queda. El modelo reproduce el patrón superficial que ha visto decenas de miles de veces y no tiene ningún libro de cuentas interno que advierta que el valor se ha invertido.
Y esto es crucial: es un problema de convención, y verificamos que no es un problema de capacidad. Construimos un pequeño corpus de regresión con frases de descuentos y de números grandes en ambas direcciones, y lo ejecutamos contra todos los niveles de modelo que SyncTrans publica, en las dos pilas en el dispositivo y a través del motor en la nube. La inversión apareció en todos los tamaños, en todas las pilas. Los modelos más grandes formulaban la cifra equivocada con más fluidez. Cuando las mediciones tienen ese aspecto, la conclusión se escribe sola: esperar a un modelo mejor no iba a arreglar esto, así que la solución tenía que vivir fuera del modelo.
Una capa de reglas detrás del modelo
La solución en la 1.0.0 es una capa determinista de postprocesado que se sitúa detrás del traductor y vigila las expresiones numéricas con una convención asociada. Cuando una frase de descuento se analiza sin ambigüedad, la capa deja de tratarla como lenguaje y la trata como aritmética: 七折 se convierte a su valor explícito — pagar el 70%, es decir, un 30% de descuento — y luego se reexpresa en la convención propia del idioma de destino. El 折 es aritmética, así que lo resolvemos con aritmética. Los números agrupados por miríadas reciben el mismo tratamiento: la magnitud se calcula a partir de la unidad y luego se representa con la agrupación del idioma de destino.
El atractivo de esta capa es que es aburrida. Cada regla es una función pequeña, con pruebas unitarias y una respuesta fija, fijada por el mismo corpus que demostró el error. Cuando una regla se dispara, podemos decir exactamente por qué; cuando un modelo improvisa, no podemos. Para la única clase de frases en la que un error fluido le cuesta dinero a alguien, queríamos un componente que diera la misma respuesta siempre y que pudiera auditarse línea a línea.
Lo que nos cuesta el enfoque híbrido
Entramos en esto con los ojos abiertos sobre los compromisos, y son reales. Una capa de reglas solo es tan buena como su cobertura, así que la primera disciplina es la contención: una regla solo se dispara cuando la frase se analiza limpiamente, y cualquier cosa ambigua se deja en manos del modelo. Una regla que adivinara corrompería resultados que el modelo habría acertado, que es el único desenlace peor que el error original. El segundo coste es el mantenimiento — las convenciones son por par de idiomas, el corpus tiene que crecer con cada par que nos tomamos en serio, y cada regla necesita mediciones en ambos lados. Y el modelo sigue haciendo todo lo demás: la prosa, el tono, el contexto. Las reglas son una red de seguridad para una clase estrecha y medible de fallos, mantenida deliberadamente demasiado pequeña para convertirse en un segundo traductor.
En qué punto está esto
Las reglas de números se publicaron en SyncTrans 1.0.0 y el corpus se ejecuta en nuestra suite de regresión, así que cualquier futura actualización de modelo tendrá que seguir superándolo. El trabajo no está terminado: el blindaje en torno a los límites de los números grandes — unidades mixtas, magnitudes dichas en formas coloquiales poco estrictas — sigue en curso, y esperamos que el corpus siga creciendo a medida que las conversaciones reales nos enseñen nuevas maneras de equivocarnos. Si alguna vez un número sale de SyncTrans con aspecto de invertido o reducido, cuéntanoslo — ese informe va directo al corpus.
Para la historia completa de qué más incluye la versión 1.0.0, consulta El camino hasta SyncTrans 1.0.