@ -14,7 +14,109 @@ import os
PDF_PATH = " TaniaBorecMemoir(Ukr).pdf " # Fichier original
PDF_PATH = " TaniaBorecMemoir(Ukr).pdf " # Fichier original
OLLAMA_MODEL = " traductionUkrainienVersFrancais:latest "
OLLAMA_MODEL = " traductionUkrainienVersFrancais:latest "
OLLAMA_URL = " http://localhost:11434/api/generate " # URL par défaut d'Ollama
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//> \n System: { info [ ' system ' ] } <br//> \n Temperature: { info [ ' temperature ' ] } <br//> \n Date de modification: { formatted_date } "
else :
return " Informations du modèle non disponibles "
def extract_text_from_pdf ( pdf_path ) :
def extract_text_from_pdf ( pdf_path ) :
""" Extrait le texte page par page d ' un PDF sans les numéros de pages. """
""" 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
return paragraphs
def send_to_ollama ( prompt , model = OLLAMA_MODEL , context_size = 128000 ) :
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. """
""" 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 \n Traduis le texte suivant de l ' ukrainien vers le { target_lang } : \n { text } "
payload = {
payload = {
" model " : model ,
" model " : model ,
" prompt " : prompt ,
" prompt " : full_ prompt,
" stream " : False ,
" stream " : False ,
" options " : { " num_ctx " : context_size }
" options " : { " num_ctx " : context_size }
}
}
@ -141,8 +245,9 @@ def create_pdf_from_results(results, output_path):
fontName = font_name
fontName = font_name
)
)
# Titre
# Titre avec la langue cible
story . append ( Paragraph ( " Traduction - Ukrainien vers Français " , title_style ) )
title_text = f " Traduction - Ukrainien vers { TARGET_LANGUAGE . capitalize ( ) } "
story . append ( Paragraph ( title_text , title_style ) )
story . append ( Spacer ( 1 , 0.2 * inch ) )
story . append ( Spacer ( 1 , 0.2 * inch ) )
# Contenu
# Contenu
@ -152,11 +257,18 @@ def create_pdf_from_results(results, output_path):
story . append ( Paragraph ( formatted_text , body_style ) )
story . append ( Paragraph ( formatted_text , body_style ) )
story . append ( Spacer ( 1 , 0.1 * inch ) )
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
# Construction du PDF
doc . build ( story )
doc . build ( story )
print ( f " PDF généré avec succès : { output_path } " )
print ( f " PDF généré avec succès : { output_path } " )
def main ( ) :
def main ( ) :
# Affiche les informations du modèle LLM
display_llm_info ( )
# Extraction du texte page par page
# Extraction du texte page par page
pages = extract_text_from_pdf ( PDF_PATH )
pages = extract_text_from_pdf ( PDF_PATH )
print ( f " Nombre de pages extraites : { len ( pages ) } " )
print ( f " Nombre de pages extraites : { len ( pages ) } " )
@ -170,10 +282,9 @@ def main():
# Traitement des paragraphes complets
# Traitement des paragraphes complets
for i , paragraph_text in enumerate ( paragraphs , start = 1 ) :
for i , paragraph_text in enumerate ( paragraphs , start = 1 ) :
print ( f " { 15 * ' - ' } Traduction du paragraphe { i } / { len ( paragraphs ) } ... \n { paragraph_text } \n " )
print ( f " { 15 * ' - ' } Traduction du paragraphe { i } / { len ( paragraphs ) } ... " )
prompt = f " Traduis le texte suivant de l ' ukrainien vers le français : { paragraph_text } "
try :
try :
result = send_to_ollama ( prompt )
result = send_to_ollama ( paragraph_text , target_lang = TARGET_LANGUAGE )
print ( f " { result } . " )
print ( f " { result } . " )
results [ i ] = result
results [ i ] = result
except Exception as e :
except Exception as e :