Journal Traduire un flux rss à la volée

Posté par  (site web personnel, Mastodon) . Licence CC By‑SA.
13
18
sept.
2024

Bonjour à tous,

Dans le cadre de ma veille technologique, je suis abonné à plusieurs flux RSS anglophones. Bien que la lecture en anglais ne me pose pas de problème majeur, elle nécessite néanmoins une concentration accrue, ce qui demande plus d'énergie et de temps.

Un flux RSS étant une liste d'articles parmi lesquels on sélectionne ceux qui nous intéressent, la navigation est rapide en français dans mon agrégateur (FreshRSS). En revanche, le processus est plus lent pour les contenus en anglais.

J'ai donc eu l'idée de créer une version traduite en français de ces flux. La solution s'est avérée étonnamment simple à mettre en place. Les prérequis sont :
1. Un système Linux (dans un Docker, un VPS ou autre)
2. Python 3.x
3. Un endpoint d'inférence (Ollama, Groq, Together AI, OpenAI, etc.)
4. Un serveur web basique (Apache suffit)
5. Le script que je vais vous présenter

Dans mon cas, Linux tourne sur la même machine physique que mon instance FreshRSS (un Proxmox hébergé chez moi qui gère plusieurs services). Pour l'inférence, j'utilise habituellement une instance d'Ollama sur une machine Linux puissante équipée de deux cartes NVIDIA Quadro Pro 5000. Cependant, cette configuration étant énergivore, je ne l'active qu'en cas de besoin. Pour ce script, j'ai donc opté pour l'API compatible OpenAI de Groq, qui est gratuite et fonctionne bien avec le modèle LLaMA 3.1 70B (la version 8B devrait également convenir, moyennant un ajustement du prompt).

Voici le script en question :

import requests
import json
import sys

# Configuration de l'API compatible OpenAI
API_KEY = 'VOTRE CLE'  # Remplacez par votre clé API OpenAI
MODEL = 'llama-3.1-70b-versatile'  # Modèle de traduction à utiliser
#URL = 'https://api.openai.com/v1/chat/completions'
URL = 'https://api.groq.com/openai/v1/chat/completions'

#fonction de traduction
def traduire_texte(texte):
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {API_KEY}',
    }
    data = {
        'model': MODEL,
        'messages': [{
            'role': 'user',
            'content': f'Voici un flux rss à traduire en français. Ne traduis pas les balises. Retourne le résultat sous format RSS brut sans formatage Markdown, retourne le texte encodé en utf-8: {texte}'
        }]    
     }
    #print(texte)
    response = requests.post(URL, headers=headers, json=data)
    #print(response.text)
    return response.json()['choices'][0]['message']['content']


#fonction qui écrit le fichier rss
def ecrire_fichier_rss(articles, nom_fichier):
    with open(nom_fichier, 'w', encoding='utf-8') as f:
        f.write(articles)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python script.py <url_flux_rss> <nom_fichier_sortie>")
        sys.exit(1)

    url_flux = sys.argv[1]
    nom_fichier_sortie = sys.argv[2]
    # Faire une requête GET à l'URL spécifiée
    response = requests.get(url_flux)

    # Vérifier si la requête a réussi
    if response.status_code == 200:
        # Charger le contenu de la page dans une variable
        page_content = response.text
        print("Contenu de la page chargé avec succès.")
    else:
        print(f"Erreur lors du chargement de la page : {response.status_code}")


    articles_traduit = traduire_texte(page_content)
    ecrire_fichier_rss(articles_traduit, nom_fichier_sortie)

voici ma ligne de crontab pour l'appeler:

10 * * * * /usr/bin/python3 /opt/scripts/traductionrss.py https://techcrunch.com/feed /home/docker-data/apache/techcrunch.rss 2>&1
Une fois le script en place, il suffit de s'abonner à l'URL http://192.168.2.202:8880/techcrunch.rss dans FreshRSS, par exemple.

Ce script, bien que rudimentaire, me rend déjà un grand service. Je surveillerai son efficacité et sa fiabilité à l'usage, et l'améliorerai si nécessaire.

N'hésitez pas à partager vos retours ou suggestions d'amélioration !

  • # .

    Posté par  . Évalué à 6 (+4/-0). Dernière modification le 18 septembre 2024 à 14:40.

    Sympa comme idée. Un peu de ingénierie rapide prompt engineering. pardon d'ingénierie d'instruction générative

    nécessite néanmoins une concentration accrue, ce qui demande plus d'énergie et de temps.

    J'imagine que ça dépend du sujet. Mais pour de l'anglais technique d'un domaine maîtrisé, j'imagine que ça me fatiguerait plus de lire une traduction que la V.O. ; ce demander qu'est qui a bien pu donner la traduction "interrupteur" ; ah bah oui, switch.
    Je ne sais pas si ça pourrait être corrigé par un pré-prompt.

    D'autre part, tu perds toute la mise en page ; je me demande ce que ça rend si il y a du code ou des images ou des listes.

    Je me demande si on ne pourrait pas utiliser les API Mozilla/Firefox pour faire le job, elle marche bien dans le navigateur et pour plein de langues.

    • [^] # Re: .

      Posté par  . Évalué à 3 (+1/-0). Dernière modification le 18 septembre 2024 à 15:33.

      J'imagine que ça dépend du sujet. Mais pour de l'anglais technique d'un domaine maîtrisé, j'imagine que ça me fatiguerait plus de lire une traduction que la V.O. ; ce demander qu'est qui a bien pu donner la traduction "interrupteur" ; ah bah oui, switch.

      J'étais entrain de lire QUIC is not quick enough over fast internet et pour l'exercice j'ai donné des bouts du premier paragraphe à chatgpt (j'y connais rien c'est le premier au quel j'ai pensé) pour voir

      • Les interfaces syscall sont un désordre, les API primitives sont trop lentes pour des paquets de taille régulière (~1500 octets), et les surcoûts sont trop élevés. GSO aide, mais c'est une API horrible, et elle a été buguée même récemment en raison de sa complexité et de normes de code médiocres.

      • Le coût des syscalls a encore augmenté avec la mitigation de Spectre – et cette histoire n'est probablement pas terminée. Nous avons besoin d'un remplacement pour les sockets BSD / APIs POSIX, elles sont terribles cette décennie. Oui, uring est sophistiqué, mais il existe un juste milieu au niveau API qui pourrait être sûr et avoir 10 fois moins de surcoût sans avoir à recourir à la complexité d'uring.

      • Les tampons UDP du système sont beaucoup trop petits par défaut – ils sont bien plus petits que leurs homologues TCP, pratiquement personne à part des experts ne les utilise, et ces experts se contentent de les ajuster.

      • Des optimisations de la pile UDP sont possibles (comme la réutilisation possible de la recherche de route sans connect(2)), GSO le démontre, bien que, comme mentionné ci-dessus, GSO soit très faillible, assez coûteux, et que la conception soit totalement inutilement complexe pour ce dont nous avons besoin, en particulier si nous voulons le faire en toute sécurité depuis un espace utilisateur non privilégié.

      J'imagine que "tampon UDP", "pile UDP" ou "espace utilisateur non privilégié" peuvent irriter les plus anglophones, mais moi j'aime bien perso (le 3ème est un peu long). Et il a maintenu le formatage. Mon prompt c'était uniquement le mot "traduit" suivi d'un copier/coller entre guillemet. Évidement les formulations ne sont pas parfaites, mais mon anglais pas assez bons pour savoir si les formulations initiales sont beaucoup mieux ou pas.

      https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

    • [^] # Re: mise en page

      Posté par  (site web personnel, Mastodon) . Évalué à 3 (+1/-0). Dernière modification le 18 septembre 2024 à 18:23.

      Alors, pour la mise en page, c'est l'agrégateur de RSS qui fait le boulot.
      Par contre, il faut que le modèle garde le XML intact, sinon cela ne fonctionne pas.
      Mais avec les gros modèles, cela semble fonctionner.

      Autrement, pour le rendu, voici une capture d'écran :
      Capture écran flux rss traduit

  • # Sécurité

    Posté par  . Évalué à 5 (+3/-0).

    Intéressant.

    J'ai lu que les IA étaient très sujets à l'injection de code; c'est à dire qu'elles ont du mal à distinguer les instructions des données à traiter. C'était peut-être un défaut de jeunesse qui n'existe plus, sinon ça pourrait donner des choses rigolotes selon le texte contenu dans le RSS.

    • [^] # Re: Sécurité

      Posté par  . Évalué à 3 (+1/-0).

      Ca existe toujours, c'est meme le risque numero 1 selon owasp LLM top 10.

      • [^] # Re: Sécurité

        Posté par  . Évalué à 3 (+1/-0). Dernière modification le 18 septembre 2024 à 18:33.

        J'ai du mal à voir le problème que poserait une injection de prompt ici. Il faudrait que celui qui émet le flux rss veulent sache manipuler le LLM pour produire une XSS. Ça me paraît faible comme danger

        https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: Sécurité

          Posté par  . Évalué à 3 (+0/-0).

          Plutôt la "blague" de l'ami qui veut tester ta crédulité en insérant des fausses infos dans la fil.

          • [^] # Re: Sécurité

            Posté par  . Évalué à 3 (+1/-0).

            Qu'est-ce qu'apporte le LLM pour ça ? Si tu suis déjà son flux RSS il peut te débiter tout ce qui lui chante

            https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

            • [^] # Re: Sécurité

              Posté par  . Évalué à 3 (+0/-0).

              Une certaine personnalisation, genre seuls les utilisateurs de ce logiciel (rares probablement) voient le canular tandis que les autres voient du contenu "normal", potentiellement.

            • [^] # Re: Sécurité

              Posté par  . Évalué à 3 (+1/-0).

              Si tu maitrises un des fils RSS, tu pourrais modifier le contenu des autres fils que tu ne maitrises pas.

              • [^] # Re: Sécurité

                Posté par  . Évalué à 2 (+0/-0).

                Pas d'après la doc de l'API qu'il utilise (il semble que c'est trop compliqué pour groq de documenter leur API… - je trouve ça vraiment dingue -) :

                Including conversation history is important when user instructions refer to prior messages. In the example above, the user's final question of "Where was it played?" only makes sense in the context of the prior messages about the World Series of 2020. Because the models have no memory of past requests, all relevant information must be supplied as part of the conversation history in each request. If a conversation cannot fit within the model’s token limit, it will need to be shortened in some way.

                https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.