Crea un traductor local de 140 idiomas con el modelo LLM Gemma 3 y Ollama.
En inteligencia artificial, los modelos de lenguaje de gran tamaño (LLM, por sus siglas en inglés) son una tecnología disruptiva que está transformando por completo el panorama tecnológico actual. La competencia entre modelos es enorme, y cada día surgen noticias sobre nuevos avances: modelos más precisos que requieren menos recursos. Hoy en día es posible hacer cosas que, hasta hace pocos años, parecían impensables y además utilizando hardware accesible para el gran público.
Un buen ejemplo es justamente el que nos ocupa: implementar un traductor como aplicación web que puede soportar hasta 140 idiomas. Utilizaremos el modelo Gemma 3 de Google. Aunque existen varias versiones, con diferentes tamaños de parámetros (1B, 4B, 12B y 27B), en este caso emplearemos la versión de 4B, que ocupa unos 3.3 GB y puede ejecutarse en prácticamente cualquier dispositivo. Naturalmente, los resultados serán algo menos precisos que con los modelos más grandes, pero aun así estamos ante un modelo sorprendente por su capacidad y velocidad.
Debes tener Ollama instalado. Puedes ejecutar este modelo para que la API esté funcionando cuando más adelante evíes el texto a traducir desde el formulario:
ollama run gemma3:4b
Antes de nada necesitamos un formulario en HTML para insertar el texto a traducir, seleccionar el idioma y traducir el texto. En la lista de idiomas sólo hemos puesto algunos, pero según la descripción del modelo soporta hasta 140!
<form id="translation-form"> <label for="input-text">Texto a traducir:</label> <textarea id="input-text" rows="5" placeholder="Escribe aquí algun texto..."></textarea> <label for="language-select">Traducir a:</label> <select id="language-select"> <option value="English">English</option> <option value="Catalan">Catalan</option> <option value="Spanish">Spanish</option> <option value="French">French</option> <option value="German">German</option> <option value="Chinese">Chinese</option> <option value="Japanese">Japanese</option> <option value="Russian">Russian</option> <option value="Arabic">Arabic</option> <option value="Portuguese">Portuguese</option> <option value="Italian">Italian</option> </select> <label for="translated-text">Texto traducido:</label> <textarea id="translated-text" rows="5" readonly></textarea> <button type="reset">Reset</button> <button type="button" id="translate-btn">Traducir</button></form>
También definimos algunos estilos básicos para el diseño del formulario:
body { font-family: Arial, sans-serif; margin: 20px;}
.textarea-container { display: flex; justify-content: space-between; margin-bottom: 15px;}
.textarea-container>div { flex: 1; margin-right: 10px;}
.textarea-container>div:last-child { margin-right: 0;}
textarea { width: 100%; padding: 10px; font-size: 16px; resize: vertical;}
.button-container { display: flex; justify-content: flex-start;}
button { padding: 10px 20px; font-size: 16px; margin-right: 10px; cursor: pointer;}
button:disabled { cursor: not-allowed; opacity: 0.6;}
Primero definiremos algunas variables y selectores de los elementos HTML:
const baseUrl = 'http://localhost:11434/api';const translateBtn = document.getElementById('translate-btn');const languageSelect = document.getElementById('language-select');const inputText = document.getElementById('input-text');const translatedText = document.getElementById('translated-text');
A continuación gestionamos el evento de clic al pulsar el botón de traducir. Aquí es importante las instrucciones que incluímos para ayudar al modelo a que nos traduzca el texto al idioma especificado junto con el idioma a traducir y el texto que queremos traducir:
translateBtn.addEventListener('click', () => { const text = inputText.value.trim(); const language = languageSelect.value; const prompt = `You are a translator bot. You are provided with a text to be translated. Identify the language ad translate it to '${language}'.Your response should be only the translation of the original user message. If you weren't able to understand the user's message or could not identify the language used,tell the user. This is the text: ${text}`;
if (prompt) { streamTranslation(prompt); } else { translatedText.value = 'Entra en texto a traducir.'; }});
Finalmente la función streamTranslation
que se encarga de conectar con Ollama y obtener la respuesta mediante la lectura del stream.
async function streamTranslation(prompt) { translateBtn.disabled = true; translatedText.value = '';
try { const response = await fetch(`${baseUrl}/generate`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'gemma3:4b', prompt: prompt, stream: true }), });
if (!response.ok) { throw new Error('La petición traducción ha fallado'); }
const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = '';
while (true) { const { done, value } = await reader.read(); if (done) break;
buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop();
for (const line of lines) { if (line.trim()) { try { const json = JSON.parse(line); if (json.response) { translatedText.value += json.response; translatedText.scrollTop = translatedText.scrollHeight; } } catch (e) { console.error('Error parseando el JSON:', e); } } } }
if (buffer.trim()) { try { const json = JSON.parse(buffer); if (json.response) { translatedText.value += json.response; } } catch (e) { console.error('Error parseando el JSON:', e); } } } catch (error) { console.error('Error durante la traducción:', error); translatedText.value = 'La traducción ha fallado, iténtalo de nuevo.'; } finally { translateBtn.disabled = false; }}
Es importante destacar que, para que la API de Ollama funcione correctamente en nuestro entorno local, debemos asegurarnos de que esté en ejecución. Además, debemos ejecutar el siguiente comando antes de iniciar Ollama para permitir llamadas CORS (Cross-Origin Resource Sharing):
launchctl setenv OLLAMA_ORIGINS "*"
Este comando configura la variable de entorno necesaria para que la API acepte peticiones desde cualquier origen para no tener errores durante el desarrollo local.
Ya ves lo sencillo que es implementar un traductor local utilizando Gemma 3 y la API de Ollama. Hay que tener en cuenta que este modelo es un poco limitado pero igualmente sorpredente. Si tienes más capacidad en tu máquina prueba con los modelos de más parámetros.