# Instalare dependențe (rulați o singură dată în Colab) !pip install transformers torch tqdm numpy pdfplumber import os from google.colab import files import torch from transformers import MarianTokenizer, MarianMTModel import numpy as np from tqdm import tqdm import pdfplumber import io # Adăugat pentru a rezolva eroarea # Variabile globale pentru model și tokenizer MODEL = None TOKENIZER = None DEVICE = None MAX_LENGTH_SOURCE = 512 MAX_LENGTH_TARGET = 512 def setup_translation(from_code, to_code, device): """Configurează modelul de traducere MarianMT cu PyTorch""" global MODEL, TOKENIZER, DEVICE, MAX_LENGTH_SOURCE, MAX_LENGTH_TARGET model_name = f"Helsinki-NLP/opus-mt-{from_code}-{to_code}" try: print(f"Încarc modelul {model_name}...") TOKENIZER = MarianTokenizer.from_pretrained(model_name) MODEL = MarianMTModel.from_pretrained(model_name) MODEL.to(device) MODEL.eval() DEVICE = device print(f"Model {model_name} încărcat pe {device}.") except Exception as e: print(f"Eroare la configurarea modelului {model_name}: {str(e)}") raise def select_device(): """Detectează și selectează dispozitivul (GPU -> CPU)""" if torch.cuda.is_available(): device = torch.device("cuda") device_name = f"GPU ({torch.cuda.get_device_name(0)})" print(f"GPU detectat: {device_name}") else: device = torch.device("cpu") device_name = "CPU" print("Niciun GPU detectat, folosesc CPU") return device, device_name def choose_language(): """Alege limbile sursă și destinație""" print("Vrei să folosești traducerea implicită EN -> RO? (da/nu)") choice = input().strip().lower() if choice in ["da", "d", "yes", "y"]: return "en", "ro" if choice not in ["nu", "n", "no"]: print("Răspuns invalid. Folosesc implicit EN -> RO.") return "en", "ro" languages = [ ("en", "Engleză"), ("es", "Spaniolă"), ("fr", "Franceză"), ("de", "Germană"), ("zh", "Chineză"), ("ru", "Rusă"), ("ar", "Arabă"), ("ro", "Română") ] print("\nSelectează limba sursă (introduce numărul):") for i, (code, name) in enumerate(languages, 1): print(f"{i}. {name} ({code})") try: from_idx = int(input()) - 1 if not 0 <= from_idx < len(languages): raise ValueError from_code = languages[from_idx][0] except (ValueError, IndexError): print("Selecție invalidă. Folosesc implicit Engleză (en).") from_code = "en" print("\nSelectează limba destinație (introduce numărul):") for i, (code, name) in enumerate(languages, 1): print(f"{i}. {name} ({code})") try: to_idx = int(input()) - 1 if not 0 <= to_idx < len(languages) or to_idx == from_idx: raise ValueError to_code = languages[to_idx][0] except (ValueError, IndexError): print("Selecție invalidă. Folosesc implicit Română (ro).") to_code = "ro" return from_code, to_code def extract_text_from_pdf(file_content): """Extrage textul dintr-un fișier PDF""" try: with pdfplumber.open(io.BytesIO(file_content)) as pdf: text = "" for page in pdf.pages: page_text = page.extract_text() if page_text: text += page_text + " " return text.strip() except Exception as e: print(f"Eroare la extragerea textului din PDF: {str(e)}") return "" def split_long_sentence(sentence, max_length=MAX_LENGTH_SOURCE): """Împarte o propoziție lungă în segmente mai mici""" tokens = TOKENIZER.encode(sentence, add_special_tokens=False) if len(tokens) <= max_length: return [sentence] segments = [] current_segment = [] current_length = 0 for token in tokens: if current_length + 1 > max_length - 2: # Rezervăm spațiu pentru BOS/EOS segments.append(TOKENIZER.decode(current_segment, skip_special_tokens=True)) current_segment = [token] current_length = 1 else: current_segment.append(token) current_length += 1 if current_segment: segments.append(TOKENIZER.decode(current_segment, skip_special_tokens=True)) return segments def translate_batch(sentences, device_name): """Tradu un batch de propoziții folosind GPU""" try: print(f"Procesez batch cu {len(sentences)} propoziții pe {device_name}") inputs = TOKENIZER(sentences, return_tensors="pt", padding=True, truncation=True, max_length=MAX_LENGTH_SOURCE).to(DEVICE) with torch.no_grad(): outputs = MODEL.generate(**inputs, max_length=MAX_LENGTH_TARGET, num_beams=1) translated_texts = TOKENIZER.batch_decode(outputs, skip_special_tokens=True) return translated_texts except Exception as e: print(f"Eroare la procesarea batch-ului: {str(e)}") return ["" for _ in sentences] def translate_file(file_content, file_name, output_dir, device_name): """Tradu un fișier (txt sau pdf) folosind PyTorch""" try: print(f"Procesez: {file_name} cu {device_name}") if file_name.endswith('.txt'): text = file_content.decode('utf-8') elif file_name.endswith('.pdf'): text = extract_text_from_pdf(file_content) if not text: print(f"Nu s-a putut extrage text din {file_name}. Poate conține doar imagini.") return else: print(f"Format neacceptat pentru {file_name}. Se acceptă doar .txt și .pdf.") return text_size_mb = len(file_content) / (1024 * 1024) if text_size_mb > 100: print(f"Atenție: {file_name} are {text_size_mb:.2f} MB. Poate depăși limitele Colab!") raw_sentences = [s.strip() + '.' for s in text.split('.') if s.strip()] sentences = [] for sentence in raw_sentences: segments = split_long_sentence(sentence) sentences.extend(segments) translated_sentences = [] batch_size = 32 output_path = os.path.join(output_dir, file_name.rsplit('.', 1)[0] + '_translated.txt') with tqdm(total=len(sentences), desc=f"Traduc {file_name}", leave=False) as pbar: for i in range(0, len(sentences), batch_size): batch = sentences[i:i + batch_size] translated_batch = translate_batch(batch, device_name) translated_sentences.extend(translated_batch) pbar.update(len(batch)) if i % 1000 < batch_size and i > 0: partial_text = " ".join(translated_sentences) with open(output_path, 'w', encoding='utf-8') as f: f.write(partial_text) print(f"Salvat progres parțial pentru {file_name} la {i} propoziții.") translated_text = " ".join(translated_sentences) with open(output_path, 'w', encoding='utf-8') as f: f.write(translated_text) print(f"Complet: {file_name}") files.download(output_path) except Exception as e: print(f"Eroare la procesarea {file_name}: {str(e)}") def translate_files(): """Procesează traducerea mai multor fișiere""" from_code, to_code = choose_language() print(f"\nTraducere selectată: {from_code} -> {to_code}") device, device_name = select_device() setup_translation(from_code, to_code, device) print("Încarcă fișierele .txt sau .pdf de tradus:") uploaded = files.upload() if not uploaded: print("Niciun fișier încărcat. Program terminat.") return output_dir = f"/content/{to_code}" os.makedirs(output_dir, exist_ok=True) print(f"\nProcesez {len(uploaded)} fișiere folosind {device_name}...") for file_name, file_content in uploaded.items(): if file_name.endswith(('.txt', '.pdf')): translate_file(file_content, file_name, output_dir, device_name) print(f"\nTraducere completă! Fișierele sunt în folderul '{to_code}' și vor fi descărcate.") if __name__ == "__main__": translate_files()