--- name: translate_es_to_en kind: function lang: py domain: datascience version: "1.0.0" purity: impure signature: "def translate_es_to_en(text: str, tokenizer: Any, model: Any, max_length: int = 512, num_beams: int = 4) -> str" description: "Traduce texto espanol a ingles frase a frase usando MarianMT. Divide por boundaries de oracion, traduce cada una independientemente y une con espacio. Preserva nombres propios mejor que pasar el parrafo entero." tags: [marianmt, translation, es-en, nlp, datascience, python, pendiente-usar] uses_functions: [marianmt_es_en_load_model_py_datascience] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [re] params: - name: text desc: "texto en espanol a traducir — puede ser una frase o un parrafo multi-oracion" - name: tokenizer desc: "tokenizer MarianMT cargado con marianmt_es_en_load_model" - name: model desc: "modelo MarianMT cargado con marianmt_es_en_load_model" - name: max_length desc: "longitud maxima en tokens por oracion para tokenizacion y generacion (defecto 512)" - name: num_beams desc: "numero de beams para beam search — mas alto = mejor calidad, mas lento (defecto 4)" output: "texto traducido al ingles. Frases unidas con espacio simple. String vacio si el input es vacio." tested: true tests: - "texto vacio retorna string vacio" - "una frase en espanol produce output no vacio" test_file_path: "python/functions/datascience/tests/test_translate_es_to_en.py" file_path: "python/functions/datascience/translate_es_to_en.py" notes: | impure: invoca model.generate que depende del estado del modelo (pesos, device). El split por oracion usa regex lookahead-behind sobre [.!?] seguidos de espacio. Esto preserva nombres propios con puntos (S.A., U.S.A.) mejor que NLTK sent_tokenize porque no usa reglas de abreviacion — simplemente divide donde hay espacio despues de puntuacion terminal. Util como preprocesador para rebel_load_model (English-only, Apache 2.0): ES text -> translate_es_to_en -> EN text -> REBEL -> triplets Alternativa directa: mrebel_load_model (multilingue, CC BY-NC-SA). --- ## Ejemplo ```python from python.functions.datascience.marianmt_es_en_load_model import marianmt_es_en_load_model from python.functions.datascience.translate_es_to_en import translate_es_to_en tokenizer, model = marianmt_es_en_load_model() text = "Pablo Isla es presidente de Inditex. La empresa tiene sede en Arteixo." translated = translate_es_to_en(text, tokenizer, model) # "Pablo Isla is president of Inditex. The company is headquartered in Arteixo." ``` ## Por que frase a frase Pasar el parrafo entero a MarianMT puede degradar la traduccion de nombres propios porque el modelo redistribuye la atencion sobre el contexto completo. Dividir por oraciones: 1. Contexto mas corto → menos confusion en nombres propios. 2. Truncation menos probable (512 tokens alcanza para oraciones normales). 3. Pipeline mas predecible para debugging (se puede inspeccionar cada frase). ## Patron pipeline ES -> EN -> REBEL ```python # Paso 1: cargar modelos mt_tok, mt_model = marianmt_es_en_load_model() rebel_tok, rebel_model = rebel_load_model() # Paso 2: traducir en_text = translate_es_to_en(es_text, mt_tok, mt_model) # Paso 3: extraer relaciones inputs = rebel_tok(en_text, return_tensors="pt", max_length=512, truncation=True) generated = rebel_model.generate(**inputs, num_beams=4, max_length=256) decoded = rebel_tok.decode(generated[0], skip_special_tokens=False) triplets = parse_rebel_output(decoded) ```