bambadij commited on
Commit
f821485
1 Parent(s): b26ba8a
Files changed (3) hide show
  1. Dockerfile +21 -9
  2. app.py +75 -48
  3. requirements.txt +1 -0
Dockerfile CHANGED
@@ -1,17 +1,29 @@
1
  # Utiliser l'image officielle d'Ollama comme base
2
  FROM ollama/ollama
3
 
4
- # Exposer le port 11434
5
- EXPOSE 11434
 
 
 
 
 
 
 
 
 
 
6
 
7
  # Définir le volume pour les données d'Ollama
8
  VOLUME /root/.ollama
9
 
10
- # Commande pour démarrer Ollama
11
- CMD ["ollama", "serve"]
12
-
13
- # Script pour exécuter llama3 après le démarrage du conteneur
14
- RUN echo '#!/bin/sh\nollama run llama3' > /run-llama3.sh && chmod +x /run-llama3.sh
 
 
15
 
16
- # Définir le point d'entrée pour exécuter Ollama et llama2
17
- ENTRYPOINT ["/bin/sh", "-c", "/run-llama3.sh & ollama serve"]
 
1
  # Utiliser l'image officielle d'Ollama comme base
2
  FROM ollama/ollama
3
 
4
+ # Installer Python et pip
5
+ RUN apt-get update && apt-get install -y python3 python3-pip
6
+
7
+ # Copier les fichiers de l'application
8
+ COPY app.py /app/app.py
9
+ COPY requirements.txt /app/requirements.txt
10
+
11
+ # Installer les dépendances Python
12
+ RUN pip3 install -r /app/requirements.txt
13
+
14
+ # Exposer le port 7860 pour FastAPI
15
+ EXPOSE 7860
16
 
17
  # Définir le volume pour les données d'Ollama
18
  VOLUME /root/.ollama
19
 
20
+ # Script pour télécharger le modèle Llama, exécuter Ollama et FastAPI
21
+ RUN echo '#!/bin/sh\n\
22
+ ollama serve &\n\
23
+ sleep 10\n\
24
+ ollama pull llama2\n\
25
+ python3 /app/app.py\n\
26
+ ' > /run-ollama-fastapi.sh && chmod +x /run-ollama-fastapi.sh
27
 
28
+ # Définir le point d'entrée
29
+ ENTRYPOINT ["/bin/sh", "/run-ollama-fastapi.sh"]
app.py CHANGED
@@ -1,58 +1,85 @@
1
- import gradio as gr
2
- from transformers import AutoModelForCausalLM, AutoTokenizer
 
 
3
  import os
4
- # Configuration du modèle et du tokenizer
5
-
6
- # Accéder à une variable d'environnement
7
- access_token = os.getenv('MODEL_Token')
8
- # Load model directly
9
- # tokenizer = AutoTokenizer.from_pretrained("mistralai/Mixtral-8x7B-Instruct-v0.1",token=access_token)
10
- # model = AutoModelForCausalLM.from_pretrained("mistralai/Mixtral-8x7B-Instruct-v0.1",token=access_token)
11
- model_name = "camembert/camembert-base" # Remplacez par le modèle souhaité
12
- tokenizer = AutoTokenizer.from_pretrained(model_name)
13
- model = AutoModelForCausalLM.from_pretrained(model_name)
14
-
15
- default_prompt = """Bonjour,
16
- en tant qu’expert dans la gestion et le traitement de plaintes réseaux chez un opérateur de télécommunications, fais moi un descriptif clair de la situation concernant la plainte dont les informations sont fournies plus bas dans ce message. Ecris la situation en 4 ou 5 phrases claires et concises, fais comme si tu parlais à un humain et rajoutes les informations relatives au Client pour une meilleure connaissance de ce dernier ainsi que des éléments de dates/délais pour être précis sur le traitement de la plainte. N’hésites pas à innover sur le ton à utiliser car n’oublies pas que tu dois faire comme si tu parlais à un humain. Ce ton peut être adapté et ne pas toujours être le même en fonction des cas.
17
- Pour m’éviter de lire tout le détail de la plainte (voir le texte partagé plus bas), essayes de trouver toutes les informations utiles permettant de mieux appréhender la situation, par exemple : si les coordonnées GPS (Lat, Lon) sont disponibles essayes de m'indiquer le lieu où est survenue la plainte même de manière approximative. Essayes également de glaner sur internet toutes les informations pouvant aider à mieux comprendre et traiter la plainte (cela peut inclure des informations des réseaux sociaux, des concurrents, etc.) tout en priorisant dans l’analyse les informations fournies dans le texte plus bas; informations qui ont été renseignées par les experts internes chez l’opérateur de télécommunications en question et qui sont structurées en plusieurs sections :
18
- a) Un titre de la plainte
19
- b) Une section avec les Détails de la Plainte contenant l’objet, le numéro client, l’expéditeur, la date de création, les coordonnées géographiques (lat, lon)
20
- c) Une section avec les états d’avancement incluant les échanges (sous format chat) entre les différents acteurs impliqués dans le traitement de la plainte
21
- d) Une section contenant les éléments relatifs à la qualification de la plainte (type de plainte, origine, domaine, sous-domaine, etc…)
22
- e) Une section avec les fichiers joints à la plainte et autres pièces jointes pour mieux comprendre et trouver une solution à cette plainte en vue de satisfaire le Client
23
-
24
- Dans la situation que tu vas me donner (en quelques 4 ou 5 phrases comme si tu t’adresses à un humain), assures toi que les points cruciaux (voire rédhibitoires) ci-dessous sont bien présents :
25
- 1) Ecris la situation en 4 ou 5 phrases claires et concises, fais comme si tu parlais à un humain
26
- 2) Rajoutes les informations relatives au Client pour être précis sur la connaissance de ce dernier.
27
- 3) Rajoutes des éléments de dates (remontée, transfert, prise en charge, résolution, clôture, etc…) ainsi que les délais (par exemple de réponse des différents acteurs ou experts de la chaine de traitement) pour mieux apprécier l'efficacité du traitement de la plainte.
28
- 4) Rajoutes à la fin une recommandation importante afin d'éviter le mécontentement du Client par exemple pour éviter qu’une Plainte ne soit clôturée sans solution pour le Client notamment et à titre illustratif seulement dans certains cas pour un Client qui a payé pour un service et ne l'a pas obtenu, On ne peut décemment pas clôturer sa plainte sans solution en lui disant d’être plus vigilant, il faut recommander à l’équipe en charge de la plainte de le rembourser ou de trouver un moyen de donner au Client le service pour lequel il a payé (à défaut de le rembourser).
29
- 5) N’hésites pas à innover sur le ton à utiliser car n’oublies pas que tu dois faire comme si tu parlais à un humain. Ce ton peut être adapté et ne pas toujours être le même en fonction des cas.
30
  """
31
 
32
- def summarize_complaint(raw_text):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  try:
34
- # Combiner le prompt et le texte brut
35
- input_text = default_prompt + raw_text
36
 
37
- # Tokeniser le texte d'entrée
38
- input_ids = tokenizer(input_text, return_tensors="pt", padding=True, truncation=True).input_ids
 
 
 
 
 
 
39
 
40
- # Générer le texte avec le modèle
41
- outputs = model.generate(input_ids, max_length=500, num_beams=4, early_stopping=True)
42
- generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
43
 
44
- return generated_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  except Exception as e:
46
- return str(e)
47
-
48
- # Création de l'interface Gradio
49
- interface = gr.Interface(
50
- fn=summarize_complaint,
51
- inputs=gr.Textbox(label="Texte brut de la plainte"),
52
- outputs=gr.Textbox(label="Résumé généré"),
53
- title="Résumé de Plaintes",
54
- description="Entrez le texte brut d'une plainte pour obtenir un résumé généré par le modèle."
55
- )
56
 
57
  if __name__ == "__main__":
58
- interface.launch()
 
1
+ from fastapi import FastAPI, HTTPException, status, UploadFile, File
2
+ from pydantic import BaseModel
3
+ import uvicorn
4
+ import logging
5
  import os
6
+ import requests
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+
9
+ os.environ['TRANSFORMERS_CACHE'] = '/app/.cache'
10
+ os.environ['HF_HOME'] = '/app/.cache'
11
+
12
+ Informations = """
13
+ -text : Texte à résumer
14
+
15
+ output:
16
+ - Text summary : texte résumé
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  """
18
 
19
+ app = FastAPI(
20
+ title='Text Summary',
21
+ description=Informations
22
+ )
23
+
24
+ logging.basicConfig(level=logging.INFO)
25
+ logger = logging.getLogger(__name__)
26
+
27
+ app.add_middleware(
28
+ CORSMiddleware,
29
+ allow_origins=["*"],
30
+ allow_credentials=True,
31
+ allow_methods=["*"],
32
+ allow_headers=["*"],
33
+ )
34
+
35
+ DEFAULT_PROMPT = "Résumez la plainte suivante en 5 phrases concises, en vous concentrant sur les faits principaux et en évitant toute introduction générique : "
36
+
37
+ class TextSummary(BaseModel):
38
+ prompt: str
39
+
40
+ class RequestModel(BaseModel):
41
+ text: str
42
+
43
+ OLLAMA_URL = "http://localhost:11434" # URL d'Ollama dans le conteneur
44
+
45
+ @app.get("/")
46
+ async def home():
47
+ return 'STN BIG DATA'
48
+
49
+ @app.post("/generate/")
50
+ async def generate_text(request: RequestModel):
51
  try:
52
+ full_prompt = DEFAULT_PROMPT + request.text
 
53
 
54
+ response = requests.post(f"{OLLAMA_URL}/api/generate", json={
55
+ "prompt": full_prompt,
56
+ "stream": False,
57
+ "model": "llama3"
58
+ })
59
+
60
+ if response.status_code != 200:
61
+ raise HTTPException(status_code=response.status_code, detail="Erreur de l'API Ollama")
62
 
63
+ generated_text = response.json().get('response', '')
 
 
64
 
65
+ intro_phrases = [
66
+ "Voici un résumé de la plainte en 5 phrases :",
67
+ "Résumé :",
68
+ "Voici ce qui s'est passé :",
69
+ "Cette plainte a été déposée par"
70
+ ]
71
+
72
+ for phrase in intro_phrases:
73
+ if generated_text.startswith(phrase):
74
+ generated_text = generated_text[len(phrase):].strip()
75
+ break
76
+
77
+ return {"summary_text_2": generated_text}
78
+
79
+ except requests.RequestException as e:
80
+ raise HTTPException(status_code=500, detail=f"Erreur de requête : {str(e)}")
81
  except Exception as e:
82
+ raise HTTPException(status_code=500, detail=f"Erreur inattendue : {str(e)}")
 
 
 
 
 
 
 
 
 
83
 
84
  if __name__ == "__main__":
85
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt CHANGED
@@ -12,3 +12,4 @@ BeautifulSoup4==4.12.3
12
  protobuf
13
  ollama
14
  requests
 
 
12
  protobuf
13
  ollama
14
  requests
15
+ sentencepiece