Browse Source

ajout des caractéristiques technique du LLM

main
Alex 2 weeks ago
parent
commit
4525a82f46
2 changed files with 141 additions and 17 deletions
  1. 21
    8
      README.md
  2. 120
    9
      main.py

+ 21
- 8
README.md View File

@@ -14,17 +14,18 @@ Ce projet permet de traduire un document PDF page par page en utilisant un modè
---

## Création d'un modèle LLM de traduction avec Ollama
En partant de zongwei/gemma3-translator:4b, voici le fichier de customisation :
En partant du LLM [zongwei/gemma3-translator:4b](https://ollama.com/zongwei/gemma3-translator), nous allons créer un modèle optimisé pour la traduction avec Ollama.
Pour info : Inutile de le downloader, il le serra automatiquement au lancement de la commande.

```shell
FROM zongwei/gemma3-translator:4b
PARAMETER temperature 0.1
PARAMETER num_ctx 131072
SYSTEM """
Tu es un traducteur professionnel spécialisé dans la traduction de texte ukrainien vers le français.
Traduis fidèlement et naturellement en respectant l'intonation originale utilisée par l'auteur du texte.
Tu ne dois pas interpréter les pensées ou les réflexions de l'auteur.
Ne rajoutes pas de texte avant ou après le texte fourni.
Tu dois toujours répondre en français.
You are a professional translator specialising in translating Ukrainian text into English.
Translate accurately and naturally, respecting the original intonation used by the author of the text.
You must not interpret the author's thoughts or reflections.
Do not add any text before or after the text provided.
"""
```
Il faut ensuite compiler le modèle avec la commande :
@@ -64,10 +65,22 @@ ollama create traductionUkrainienVersFrancais -f .\Modelfile
```bash
ollama list
```
Vous devez voir `traductionUkrainienVersFrancais:latest` dans la liste.
Si ce n'est pas le cas, vous devez le générer en suivant la drescription vue plus haut (Création d'un modèle LLM de traduction avec Ollama)
Vous devez voir `traductionUkrainienVersFrancais` dans la liste.

Si ce n'est pas le cas, vous devez le générer comme décrit plus haut (paragraphe "Création d'un modèle LLM de traduction avec Ollama")

3. **Placer votre PDF** dans le même répertoire que le script `main.py`
### Paramétrage du script
`PDF_PATH`= "TaniaBorecMemoir(Ukr).pdf" <- Le nom du fichier pdf à traduire.
`OLLAMA_MODEL` = "mitmul/plamo-2-translate:latest" <- Le nom
`OLLAMA_URL` = "http://localhost:11434/api/generate" <- URL par défaut d'Ollama
`TARGET_LANGUAGE` = "français" <- Langue cible (ex: "français", "anglais", "allemand", "espagnol", etc.)
`SYSTEM_PROMPT` = """You are a professional translator specialising in Ukrainian text translation.
Translate accurately and naturally, respecting the original intonation used by the author of the text.
You must not interpret the author's thoughts or reflections.
Do not add any text before or after the text provided.
Preserve the layout and structure of the original text."""


### Exécution


+ 120
- 9
main.py View File

@@ -14,7 +14,109 @@ import os
PDF_PATH = "TaniaBorecMemoir(Ukr).pdf" # Fichier original
OLLAMA_MODEL = "traductionUkrainienVersFrancais:latest"
OLLAMA_URL = "http://localhost:11434/api/generate" # URL par défaut d'Ollama
OUTPUT_PDF_PATH = PDF_PATH.replace(".pdf", " (FR).pdf") # Chemin du PDF de sortie
TARGET_LANGUAGE = "français" # Langue cible (ex: "français", "anglais", "allemand", "espagnol", etc.)
OUTPUT_PDF_PATH = PDF_PATH.replace(".pdf", f" ({TARGET_LANGUAGE.upper()[:2]}).pdf") # Chemin du PDF de sortie

# Prompt système personnalisé (instructions pour le LLM)
SYSTEM_PROMPT = """"""

def extract_parameters_from_template(template_str):
"""Extrait les paramètres du modèle à partir du template."""
import re
parameters = {}
if not template_str or not isinstance(template_str, str):
return parameters
# Si la chaîne contient "parameters:", récupère ce qui suit
if 'parameters:' in template_str:
params_section = template_str.split('parameters:', 1)[1]
else:
# Sinon, utilise la chaîne directement (elle contient déjà les paramètres)
params_section = template_str
# Parse les lignes de paramètres
# Format: "stop "<end_of_turn>""
# "temperature 0.1"
lines = params_section.split('\n')
for line in lines:
if not line.strip():
continue
# Divise par le premier groupe d'espaces blancs
# Cela sépare la clé des valeurs avec leurs espaces
parts = line.split(None, 1) # split() avec maxsplit=1 divise sur les espaces
if len(parts) == 2:
param_name = parts[0].strip()
param_value = parts[1].strip()
parameters[param_name] = param_value
return parameters

def get_llm_model_info(model=OLLAMA_MODEL):
"""Extrait les informations du modèle LLM depuis Ollama."""
try:
# URL pour obtenir les informations du modèle
info_url = OLLAMA_URL.replace("/api/generate", "/api/show")
payload = {"name": model}
response = requests.post(info_url, json=payload)
if response.status_code == 200:
model_data = response.json()
# Gère le cas où model_data est une chaîne
if isinstance(model_data, str):
model_data = json.loads(model_data)
# Extrait les paramètres du template
parameters = model_data.get('parameters', '')
parsed_params = extract_parameters_from_template(parameters)
# Extraction des informations principales
info = {
"temperature": parsed_params.get('temperature', model_data.get("temperature", "Not available")),
"num_ctx": parsed_params.get('num_ctx', "Not available"),
"top_k": parsed_params.get('top_k', "Not available"),
"top_p": parsed_params.get('top_p', "Not available"),
"system": model_data.get("system", "Not available"),
"modified_at": model_data.get("modified_at", "Not available"),
}
return info
else:
print(f"Erreur lors de la récupération du modèle : {response.text}")
return None
except Exception as e:
print(f"Erreur lors de l'accès aux informations du modèle : {e}")
return None

def display_llm_info():
"""Retourne les informations du modèle LLM formatées."""
from datetime import datetime
info = get_llm_model_info(OLLAMA_MODEL)
if info:
# Formate la date en jj/mm/AAAA
modified_at = info.get('modified_at', 'Not available')
if modified_at and modified_at != 'Not available':
try:
# Parse la date ISO
date_obj = datetime.fromisoformat(modified_at.replace('Z', '+00:00'))
# Formate en jj/mm/AAAA
formatted_date = date_obj.strftime("%d/%m/%Y")
except:
formatted_date = modified_at
else:
formatted_date = 'Not available'
return f"LLM Modèle: {OLLAMA_MODEL}<br//>\nSystem: {info['system']}<br//>\nTemperature: {info['temperature']}<br//>\nDate de modification: {formatted_date}"
else:
return "Informations du modèle non disponibles"

def extract_text_from_pdf(pdf_path):
"""Extrait le texte page par page d'un PDF sans les numéros de pages."""
@@ -67,11 +169,13 @@ def merge_paragraphs_across_pages(pages_text):
return paragraphs

def send_to_ollama(prompt, model=OLLAMA_MODEL, context_size=128000):
"""Envoie une requête à Ollama et retourne la réponse."""
def send_to_ollama(text, target_lang=TARGET_LANGUAGE, model=OLLAMA_MODEL, context_size=128000, system_prompt=SYSTEM_PROMPT):
"""Envoie une requête à Ollama et retourne la réponse traduite."""
# Construit le prompt avec les instructions système et la demande de traduction
full_prompt = f"{system_prompt}\n\nTraduis le texte suivant de l'ukrainien vers le {target_lang} :\n{text}"
payload = {
"model": model,
"prompt": prompt,
"prompt": full_prompt,
"stream": False,
"options": {"num_ctx": context_size}
}
@@ -141,8 +245,9 @@ def create_pdf_from_results(results, output_path):
fontName=font_name
)
# Titre
story.append(Paragraph("Traduction - Ukrainien vers Français", title_style))
# Titre avec la langue cible
title_text = f"Traduction - Ukrainien vers {TARGET_LANGUAGE.capitalize()}"
story.append(Paragraph(title_text, title_style))
story.append(Spacer(1, 0.2*inch))
# Contenu
@@ -152,11 +257,18 @@ def create_pdf_from_results(results, output_path):
story.append(Paragraph(formatted_text, body_style))
story.append(Spacer(1, 0.1*inch))
# Infos sur le LLM
story.append(Spacer(1, 0.2*inch))
story.append(Paragraph(display_llm_info(), page_style))
# Construction du PDF
doc.build(story)
print(f"PDF généré avec succès : {output_path}")

def main():
# Affiche les informations du modèle LLM
display_llm_info()
# Extraction du texte page par page
pages = extract_text_from_pdf(PDF_PATH)
print(f"Nombre de pages extraites : {len(pages)}")
@@ -170,10 +282,9 @@ def main():
# Traitement des paragraphes complets
for i, paragraph_text in enumerate(paragraphs, start=1):
print(f"{15 * '-'} Traduction du paragraphe {i}/{len(paragraphs)}...\n{paragraph_text}\n")
prompt = f"Traduis le texte suivant de l'ukrainien vers le français : {paragraph_text}"
print(f"{15 * '-'} Traduction du paragraphe {i}/{len(paragraphs)}...")
try:
result = send_to_ollama(prompt)
result = send_to_ollama(paragraph_text, target_lang=TARGET_LANGUAGE)
print(f"{result}.")
results[i] = result
except Exception as e:

Loading…
Cancel
Save