Servicio de transcripción asequible / Sudo Null IT News

Dio la casualidad de que tenía algo de tiempo libre, que quería dedicar a una pequeña proyecto de pasatiempo, que espero que incluso tenga posibilidades de convertirse en una startup. La idea era crear un servicio de transcripción de voz a texto muy asequible. Decidí llamarlo Blobfish porque… Me gusta mucho el aspecto del pez globo. ¡Pero no hagamos alusiones al conocido meme!

En mi opinión, la competitividad de un servicio de este tipo puede estar determinada por la excepcional calidad de la transcripción o por un precio significativamente más bajo que el de la competencia. Lamentablemente, ni mis competencias ni los recursos a mi disposición me permitieron tomar el primer camino. De hecho, planeé utilizar componentes disponibles públicamente, por lo que no podía esperar una calidad sorprendente. Sólo quedaba contar con el atractivo del bajo precio. Se decidió fijar un costo de $0,002 por minuto.

Arquitectura e implementación

La idea básica de implementar un servicio de este tipo es bastante simple. El flujo de voz se divide en fragmentos que entran en el modelo fuera de línea, que los transcribe en texto. No encontré ningún modelo abierto que admita la transcripción en streaming. Por lo tanto, me centré en Whisper, que proporciona una calidad bastante alta, pero, desafortunadamente, no admite el procesamiento de transmisiones. Aquí surgió la necesidad de la mencionada segmentación del habla. Para resolver este problema, inicialmente consideré las bibliotecas VAD, pero los experimentos demostraron que no eran capaces de segmentar la voz en fragmentos completos. Al final me decidí por pyannote-audio, para el cual simplemente no había alternativas disponibles. Esta biblioteca no se maneja bien diarización (Hasta donde yo sé, este problema no está realmente resuelto hoy en día), pero puede segmentar muy bien el habla.

Sin financiación de terceros, para mí era importante elegir una arquitectura que proporcionara la máxima escalabilidad. Aquellos. En lugar de alquilar un servidor dedicado equipado con potentes tarjetas de vídeo, decidí empezar con un VPS económico, que se puede añadir según sea necesario. Si tiene éxito, puede conectar artillería CUDA pesada, nuevamente, si hay una justificación financiera. Según estos requisitos, la arquitectura del sistema proporcionó un servidor de control con una dirección IPv4 pública y muchos nodos trabajadores en los que se llevaría a cabo la transcripción. El servidor de administración recibe y decodifica la transmisión de audio del usuario a través de un socket web, redirige su versión PCM a uno de los nodos trabajadores para su segmentación y luego asigna los segmentos recibidos a los nodos trabajadores para su transcripción en tiempo real. A medida que se reciben fragmentos de texto, se devuelven al usuario a través de un conector web. El servidor de administración realiza un seguimiento de los recursos consumidos, así como de los saldos de los usuarios.

Es importante que el servidor de administración sea lo más eficiente posible, ya que la arquitectura seleccionada no prevé su replicación/fragmentación. Decidí implementarlo en Rust, porque… En los últimos años he estado escribiendo principalmente en este idioma y he llegado a amarlo (aunque creo que Go también encajaría bien en este puesto). Entonces, el servidor se basa en el ecosistema. tokio: acepta solicitudes usando axuminteractúa con PostgreSQL a través de tokio-postgreslas llamadas HTTP se realizan usando reqwesty se conecta a websockets a través de tokio-tungstenite.

Inicialmente, planeé escribir software para el nodo trabajador en Rust, pero rápidamente me di cuenta de que casi todos los modelos de IA que necesitaba estaban disponibles casi exclusivamente en Python, por lo que decidí escribir el servidor del nodo trabajador en este lenguaje. Para mí, esta no fue la elección más agradable, ya que nunca había escrito profesionalmente en Python. El conjunto de paquetes también es bastante estándar: uvicorn como servidor, pyannote-audio y faster-whisper respectivamente para segmentación y transcripción.

Como trabajé en este proyecto en un espléndido aislamiento, al no ser un desarrollador frontend, ignoré por completo el diseño web, proporcionando al usuario una simple API. Si el sistema tiene demanda, probablemente agregaré un sitio web sencillo con una demostración en línea.

Problemas

  • Dado que Whisper es un modelo fuera de línea entrenado en una ventana de tiempo de tamaño fijo (generalmente 30 segundos), debe recibir segmentos de audio bastante largos. En segmentos cortos, se desperdician recursos informáticos y la precisión de la transcripción disminuye significativamente. Por lo tanto, tuvimos que dividir la transmisión de audio en segmentos de 15 a 30 segundos. Esto significa cierto retraso durante la transcripción. Por desgracia, sólo podemos soñar con seleccionar palabras en tiempo real, como lo hace Google.

  • Dado que el proyecto, se podría decir, se redactó de rodillas sin tener en cuenta a los business angels ni a los inversores, el número de nodos de trabajo es muy pequeño y, por tanto, los recursos para la transcripción. Entonces, cuando hay una afluencia de usuarios, las fallas son inevitables. Lamentablemente, la transcripción requiere muchos recursos informáticos (como ya escribí, todavía no uso tarjetas de video para ahorrar dinero). Pero este es un problema que se puede solucionar: si hay demanda, agregaré nuevos nodos.

  • Whisper, como muchos otros modelos, sufre alucinaciones. El comportamiento del modelo es bastante decente siempre que se hable con claridad. Pero cuando hay silencio o el discurso se vuelve ilegible, de vez en cuando aparecen en la transcripción el mismo tipo de frases repetidas. Realmente no entiendo cómo lidiar con esto todavía.

Intentemos

  1. Cree un token de correo electrónico para registrarse:

    curl -X POST -H "Content-Type: application/json" -d '{"email":"vasya.pupkin@gmail.com"}'

    {}

    Debería recibir un correo electrónico con un token, que utilizaremos para registrar al usuario. Por ejemplo, así: OGcpfTLcSo2ifZQhYjkJZINuMfu/VwtfK92PsjbdjcxI4S7NkfRKEVqAVh3P6PND.

  2. Registre un usuario con un token de la carta:

    curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer OGcpfTLcSo2ifZQhYjkJZINuMfu/VwtfK92PsjbdjcxI4S7NkfRKEVqAVh3P6PND" -d '{}'

    {"id":"6319b452-b568-423c-b7d3-ff6d336f58f2","token":"6M/vC84qQnSpooQP5gVoIZiN4mWTpPeRlFVP3ugfKwLYfIh7P74FdUpFNubZzkGG","tokenId":"454d0a5f-9f8b-432e-a567-af84368d736f"}

    Guardamos de forma segura el token devuelto, ya que es la clave de la nueva cuenta. Puedes olvidar el antiguo token de verificación de correo electrónico; ya no es válido.

  3. Ahora veamos la cuenta creada:

    curl -H "Authorization: Bearer 6M/vC84qQnSpooQP5gVoIZiN4mWTpPeRlFVP3ugfKwLYfIh7P74FdUpFNubZzkGG"

    {"user":{"balance":"1.0","campaign":"05a1e610-3483-4142-bc98-3954c9eae00e","createdAt":"2024-06-16T10:13:33.165454Z","email":"vasya.pupkin@gmail.com","id":"6319b452-b568-423c-b7d3-ff6d336f58f2"}}

    Tenemos $1 en nuestra cuenta, lo que equivale a 500 minutos de transcripción.

  4. Ahora puedes transcribir. Para ello usaremos los comandos sox y websocat:

    sox -d -t vorbis -q - | websocat -bE "wss://api.blobfish.no/transcribe?tariff=basic" -H "Content-Type: audio/ogg; codecs=vorbis" -H "Authorization: Bearer 6M/vC84qQnSpooQP5gVoIZiN4mWTpPeRlFVP3ugfKwLYfIh7P74FdUpFNubZzkGG"

    {"begin":3.9290938,"end":19.82347,"text":"Именно курс, который по итогам торгов формировался на Морсбирже, используется для определения официального курса к центральным банкам. И теперь этой точки отсчёта нет. В среду днём 12 июня Минфин, американский Минфин, вёл санкции. В шесть часов вечера по Москве."}

    {"begin":20.0,"end":45.925343,"text":" В Мосбирже объявилось, что останавливает торги евро и доллар. Пропаганда отреагировала только вечером. Сухая сводка. Спокойствие, только спокойствие. Центральный банк разберётся. Под санкциями Московская биржа с завтрашнего дня она не будет проводить торги по долларам и евро. Как пояснил Центробанк, сделки продолжатся на внебиржевом рынке. А для определения курса инструментов УЦБ есть. Среди них банковская отчётка."}

    Por lo tanto, el cliente envía un flujo binario OGG Vorbis al socket web (por ahora solo está disponible este formato, en el futuro tal vez agregue Opus) y en respuesta recibe cadenas JSON con segmentos transcritos.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *