diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..f6f4518 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,30 @@ +on: + workflow_dispatch: + push: + branches: main + +name: Quarto Publish + +jobs: + build-deploy: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Update runner + run: | + sudo apt-get update + sudo apt-get install libcurl4-openssl-dev + sudo apt-get install libharfbuzz-dev libfribidi-dev libfontconfig1-dev + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Quarto + uses: quarto-dev/quarto-actions/setup@v2 + + - name: Render and Publish + uses: quarto-dev/quarto-actions/publish@v2 + with: + target: gh-pages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/Guide.md b/Guide.md index 9fb1eaa..e2e7668 100644 --- a/Guide.md +++ b/Guide.md @@ -1,42 +1,84 @@ # Guide du LLM -## Identifier clairement le besoin (Johnny / Hélène) +## PARTIE I. Accompagnement au changement -* besoin +### 1. Besoins (Johnny Hélène) -* données (collecter) + Vision high level de l'intérêt des LLMs -## Environnement institutionnel et informatique (Katia / Bruno) +### 2. Ce qui est déjà fait dans l’administration (Johnny Hélène Thibault) -* juridique de chaque admin + cas d’usage + des infras + des modeles + des datasets/open data ? -* infra (sspcloud et autres clouds) +### 3. Besoin d’Acculturation (Supports!) (Johnny Hélène CamilleB) -## Benchmark LLM (Zhanna / Malo) + Comment embarquer les métiers/personnels moins techniques + Points d'attention à partager sur l'utilisation de tels outils -* typologie LLM / choix non exhaustif de LLM testé ici +### 4. Impacts et limites (Katia Bruno Hélène) -### Evaluation avant finetuning (Daphné) + a. Environnementaux (poids de l’entraînement, poids de l’utilisation) + + b. Légaux (RGPD, chartes de l’IA, IA Act, ...) + + c. Sécurité (Renvoyer vers le guide de l’ANSSI) -* libraire d'eval ? -* librarie d'annotation (label studio / autres) -### Finetuning (ev.) et évaluation post-finetuning (Conrad ) +## PARTIE II. Développements autour des LLMs (pour les data scientists) -* Trainer (TRL) -* qlora +### 1. Revue technique de l’état de l’art LLM (Malo Jérôme) -## Benchmark RAG (Johnny / ) + a. Architectures principales LLM + + b. Méthodes de fine-tuning (Conrad) + + c. Prompt engineer (lien vers prompt guide) + + d. Quoi faire quand ? (arbre de décision) -* Librairie utilisée (RAG : Langchain/LLamaindex) +### 2. RAG (Hugo Malo Jérôme Daphné Katia) -* Techniques autour des LLM (RAG,parser) + a. pipelines, + b. Benchmark des différentes bases vectorielles (Katia) + + c. presentations de modules avec RETEX, CODE!) -## Production (Camille Brier / Conrad / Jérôme) +### 3. Évaluations (Zhanna Daphné) -* docker (image) et déploiement de l'image sur un cluster (Sspcloud ou autre) / pc local + a. Métriques (biais, hallucinations, ...) + + b. Datasets + + c. Librairies/Frameworks (CODE!) + + d. Méthodologie (arbre de décision pour le décideur) -* vllm en api (back) +### PARTIE III. Deploiements -* streamlit/dash et autres lib (front) +### 1. Socle minimal pour un LLM (Camille Jérôme Conrad) + + a. vLLM + docker ? (CODE!) + +### 2. Socle avancé (Camille Jérôme Conrad) + + Optimisation, Monitoring, UX/UI (CODE!) + +### 3. Socle pour production (Camille Jérôme Conrad) + + Orchestrateur (CODE!) + + Nvidia etc. + +### 4. Infras dispos pour l’administration (Thibault Katia) + + SSP Cloud (Onyxia) + + Cloud PI + + Clouds privés (SECNUMCLOUD, Sens?) + + (NuboNyxia à terme) diff --git a/I-Accompagnement/1_Besoins.qmd b/I-Accompagnement/1_Besoins.qmd new file mode 100644 index 0000000..353316f --- /dev/null +++ b/I-Accompagnement/1_Besoins.qmd @@ -0,0 +1,16 @@ +# Guide du LLM + +## PARTIE I. Accompagnement au changement + +### 1. Besoins (Johnny Hélène) + + Vision high level de l'intérêt des LLMs + +Les cas d'usages des LLMs sont variés et avant de se lancer et innover grâce aux LLMs, il est nécessaire de bien identifier le besoin qui amène l'utilisation d'un LLM. Pour quoi faire ? Pour quels usages ? Est-ce pour de la génération de texte ? Pour de la classification ? +L'objectif de ce chapitre est d'accompagner la réflexion autour de l'identification du besoin et de la collecte des données, avec les différents types de cas d'usages impliquant des LLMs. + + Les cas d'usages : + + * cas d'usages autour de la génération de contenu + * cas d'usage autour de la classification et de la recherche de contenu + * cas d'usage autour des interactions conversationnelles \ No newline at end of file diff --git a/I-Accompagnement/2_Deja_Fait_Admin.qmd b/I-Accompagnement/2_Deja_Fait_Admin.qmd new file mode 100644 index 0000000..450a9ea --- /dev/null +++ b/I-Accompagnement/2_Deja_Fait_Admin.qmd @@ -0,0 +1,13 @@ +# Guide du LLM + +## PARTIE I. Accompagnement au changement + +### 2. Ce qui est déjà fait ou expérimenté dans l’administration (Johnny Hélène Thibault) + + cas d’usage +* Dans une enquête incluant un champ « Commentaire », celui-ci peut être analysé par des LLMs afin d’identifier les thématiques saillantes exprimées dans ce champ. Ensuite, pour chacune de ces thématiques, les LLMs peuvent être utilisés pour dégager le sentiment prédominant (ex : positif, négatif, neutre) associé à chacune d’entre elles. In fine, grâce aux LLMs, le champ « Commentaire » peut ainsi être divisé en un nombre N de thématiques, et, pour chacune de ces thématiques, un contenu peut être généré afin de faire ressortir le sentiment majoritaire des répondants à l’enquête. + + des infras + des modeles + des datasets/open data ? + diff --git a/I-Accompagnement/3_Acculturation.qmd b/I-Accompagnement/3_Acculturation.qmd new file mode 100644 index 0000000..0afb89f --- /dev/null +++ b/I-Accompagnement/3_Acculturation.qmd @@ -0,0 +1,8 @@ +# Guide du LLM + +## PARTIE I. Accompagnement au changement + +### 3. Besoin d’Acculturation (Supports!) (Johnny Hélène CamilleB) + + Comment embarquer les métiers/personnels moins techniques + Points d'attention à partager sur l'utilisation de tels outils diff --git a/I-Accompagnement/4_Impacts.qmd b/I-Accompagnement/4_Impacts.qmd new file mode 100644 index 0000000..27daba7 --- /dev/null +++ b/I-Accompagnement/4_Impacts.qmd @@ -0,0 +1,26 @@ +# Guide du LLM + +## PARTIE I. Accompagnement au changement + +### 4. Impacts (Katia Bruno Hélène) + + a. Environnementaux (poids de l’entraînement, poids de l’utilisation) + +Le numérique est responsable de 2,5% de l’empreinte carbone de la France (17,2 Mt de CO2e & 20 millions de tonnes de déchets) selon l’étude [ARCEP & ADEME de 2023](https://www.arcep.fr/uploads/tx_gspublication/note-synthese-au-gouvernement-prospective-2030-2050_mars2023.pdf). Par contre, il n’existe aucun référentiel à ce jour pour mesurer l’impact environnemental des projets d’intelligence artificielle. À titre d'exemple, les émissions liées à l'entraînement de GPT-3 sont estimées à 552 tonnes de CO2eq [1] et son utilisation en janvier 2023 représenterait 10 113 tonnes de CO2eq [2]. Les ressources en eau, métaux et d'autres matériaux pour la fabrication et opération des infrastructures sont également conséquents. + +Afin de permettre aux acteurs du numérique d’évaluer l’impact environnemental de leurs projets d’intelligence artificielle, et de communiquer sur le caractère frugal de ces derniers, l'Ecolab du MTECT prépare avec l'AFNOR un [document de référence](https://normalisation.afnor.org/nos-solutions/afnor-spec/intelligence-artificielle-frugale/), qui devra être disponible en juillet. + +À l'heure actuelle, pour estimer la consommation énergétique et les émissions de CO2 liées à l’exécution du code, les data-scientists peuvent utiliser la librairie [CodeCarbon](https://github.com/mlco2/codecarbon), à mettre en place avant l'usage, et/ou [Green Algorithms](https://www.green-algorithms.org/), qui peut être utilisé pour estimer un usage futur ou passé. + +Le coût environnementale lié aux infrastructures de calcul est mis à disposition par le groupe EcoInfo du CNRS à travers l'outil [EcoDiag](https://ecoinfo.cnrs.fr/ecodiag-calcul/). Des estimations plus précises pour la fabrication de GPUs seront disponibles prochainement. + +[1] https://arxiv.org/pdf/2104.10350.pdf + +[2] [Data For Good - Livre Blanc de l'IA Générative](https://issuu.com/dataforgood/docs/dataforgood_livreblanc_iagenerative_v1.0?fr=sZGE0MjYyNjE5MTU) + + + + b. Légaux (RGPD, chartes de l’IA, IA Act, ...) + + c. Sécurité (Renvoyer vers le guide de l’ANSSI) + diff --git a/II-Developpements/1_Revue_Technique_LLM.qmd b/II-Developpements/1_Revue_Technique_LLM.qmd new file mode 100644 index 0000000..49422a2 --- /dev/null +++ b/II-Developpements/1_Revue_Technique_LLM.qmd @@ -0,0 +1,127 @@ +# Guide du LLM + +## PARTIE II. Développements autour des LLMs (pour les data scientists) + +### 1. Revue technique de l’état de l’art LLM (Malo Jérôme) + + a. Architectures principales LLM + + b. Méthodes de fine-tuning (Conrad) + + Les LLM sont des réseaux de neurones de taille importante et font l'objet d'entraînement avec des ressources colossales (*e.g*: quelques dizaines de milliers de GPUs dernier modèle pendant 3 mois pour `GPT-4`). L'entraînement permet d'apprendre un jeu de données particulier, en réglant l'ensemble des poids du modèles (*e.g*: `Mixtral 8x22B` est une architecture à 141 milliards de poids; 175 milliards pour `GPT-3`). Les LLM sont entraînés à répondre à plusieurs tâches génériques et ne sont pas forcément pertinent pour des cas d'utilisation particulier. + + Pour répondre à ce besoin, plusieurs méthodes relevant du principe de fine-tuning sont possibles. Le fine-tuning consiste à reprendre un modèle déjà entraîné et à l'adapter sur un jeu de données particulier sur une ou plusieurs tâches spécifiques. En général, il s'agit de modifier une partie ou l'ensemble des poids pour que le modèle soit plus précis pour les tâches voulues. Le fine-tuning garde en grande partie les bénéfices de l'entraînement initial, *i.e* les connaissances antérieurs déjà apprises. Repartir d'un modèle déjà entraîné pourra réduire le temps d'entraînement requis pour le fine-tuning, en fonction de la similarité entre la nouvelle tâche souhaitée et son jeu de données et les entraînements précédents. + + Pour des petits modèles de langages, il est possible de ré-entraîner en modifiant l'ensemble des poids. Pour des modèles plus grands, modifier l'ensemble des poids peut s'avérer couteux en temps et en GPUs. Plusieurs approches permettent de ré-entraîner à moindre coût : + * réentrainer seulement un sous-ensemble de poids + * modifier la tête de modélisation de la langue (`lm_head`) pour certains modèles, soit en réentrainant depuis les poids entraînés, soit en réinitialisant ces poids. + * garder l'intégralité du modèle et rajouter des poids à entraîner puis utiliser l'approximation de bas rang avec `LORA` (`Low-Rank Adaptation`) pour l'entraînement et l'inférence. + * utiliser des versions quantisées, i.e. des modèles où les poids ont été tronqués à une précision inférieure (possibilité de combiner avec la technique précédente, sous le nom de qLORA). + + Entraînement avec qLORA en pratique : + + En plus de la librairie `transformers` et `datasets`, les librairies `peft`, `bitsandbytes` et `trl` permettent de simplifier l'entraînement avec qLORA + + (inspiré du [notebook suivant](https://www.kaggle.com/code/kingabzpro/mistral-7b-instruct-4bit-qlora-fine-tuning) ) + + ```python +%%capture +%pip install -U bitsandbytes +%pip install -U transformers +%pip install -U peft +%pip install -U trl +%pip install -U sentencepiece +%pip install -U protobuf + +from transformers import AutoModelForCausalLM, AutoTokenizer,TrainingArguments +from peft import LoraConfig, prepare_model_for_kbit_training, get_peft_model +from datasets import load_dataset +import torch +from trl import SFTTrainer + +base_model = "teknium/OpenHermes-2.5-Mistral-7B" +new_model = "Mistral-7b-instruct-teletravail" + +path_to_training_file="Dataset_public_accords_teletravail_Dares_train.parquet" +path_to_test_file="Dataset_public_accords_teletravail_Dares_test.parquet" + + +dataset=load_dataset("parquet", data_files={'train': path_to_training_file, 'test': path_to_test_file}) + +bnb_config = BitsAndBytesConfig( + load_in_4bit= True, + bnb_4bit_quant_type= "nf4", + bnb_4bit_compute_dtype= torch.bfloat16, + bnb_4bit_use_double_quant= False, +) + +model = AutoModelForCausalLM.from_pretrained( + base_model, + quantization_config=bnb_config, + torch_dtype=torch.bfloat16, + device_map="auto", + trust_remote_code=True, +) +model.config.use_cache = False # silence the warnings. Please re-enable for inference! +model.config.pretraining_tp = 1 +model.gradient_checkpointing_enable() + +# Load tokenizer +tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True) +tokenizer.padding_side = 'right' +tokenizer.pad_token = tokenizer.eos_token +tokenizer.add_eos_token = True +tokenizer.add_bos_token, tokenizer.add_eos_token + + +model = prepare_model_for_kbit_training(model) +peft_config = LoraConfig( + lora_alpha=16, + lora_dropout=0.1, + r=64, + bias="none", + task_type="CAUSAL_LM", + target_modules=["q_proj", "k_proj", "v_proj", "o_proj","gate_proj"] +) +model = get_peft_model(model, peft_config) + +training_arguments = TrainingArguments( + output_dir="./results", + num_train_epochs=1, + per_device_train_batch_size=4, + gradient_accumulation_steps=1, + optim="paged_adamw_32bit", + save_steps=25, + logging_steps=25, + learning_rate=2e-4, + weight_decay=0.001, + fp16=False, + bf16=False, + max_grad_norm=0.3, + max_steps=-1, + warmup_ratio=0.03, + group_by_length=True, + lr_scheduler_type="constant", +) + +trainer = SFTTrainer( + model=model, + train_dataset=dataset["train"], + peft_config=peft_config, + max_seq_length= None, + dataset_text_field="text", + tokenizer=tokenizer, + args=training_arguments, + packing= False, +) + +trainer.train() + +trainer.model.save_pretrained(new_model) + + ``` + + + c. Prompt engineer (lien vers prompt guide) + + d. Quoi faire quand ? (arbre de décision) diff --git a/II-Developpements/2_RAG.qmd b/II-Developpements/2_RAG.qmd new file mode 100644 index 0000000..e2bd600 --- /dev/null +++ b/II-Developpements/2_RAG.qmd @@ -0,0 +1,9 @@ +# Guide du LLM + +## PARTIE II. Développements autour des LLMs (pour les data scientists) + +### 2. RAG (Hugo Malo Jérôme Daphné) + + a. pipelines, + + b. presentations de modules avec RETEX, CODE!) diff --git a/II-Developpements/3_Evaluations.qmd b/II-Developpements/3_Evaluations.qmd new file mode 100644 index 0000000..222a6ee --- /dev/null +++ b/II-Developpements/3_Evaluations.qmd @@ -0,0 +1,158 @@ +# Guide du LLM + +## PARTIE II. Développements autour des LLMs (pour les data scientists) + +### 3. Évaluations (Zhanna Daphné) + +#### 3.1 Objectif + +Tous les LLM visent le même objectif : maîtriser le langage naturel et par là même, égaler l'humain dans des tâches +telles que le résumé, la traduction, la reconnaissance des entités nommées, etc. + +Cependant, tous les LLM souffrent des mêmes défauts, de façon plus ou moins prononcée: + + * Très grande sensibilité du modèle au prompt utilisé + * Les affirmations produites par les LLM ne sont pas toujours factuellement correctes (on parle d'hallucinations) + * Les LLM peuvent avoir des comportements inattendus et dangereux suite à l'usage de prompts malveillants, de données + d'entraînement biaisées, au recours à des agents trop permissifs, etc. + +On souhaite donc se doter d'un cadre de comparaison qui permette d'affirmer que tel LLM est plus performant ou plus +fiable que tel autre. On devra recourir à différentes métriques pour **mesurer differents aspects** du problème +(fiabilité, sécurité, absence de biais...) + +Si de nombreux bancs d'essai existent aujourd'hui, permettant de distinguer certains LLM, **il ne faut pas oublier +que de bonnes performances dans un banc d'essai ne sont pas suffisantes, et qu'il est primordial de mettre en place un +système d'évaluation quasi temps réél du LLM une fois en production.** + +#### 3.2 Quelques concepts à connaître + +**a) Scenario** + +Un scénario est un ensemble de conditions dans lesquelles la performance du LLM est évaluée. Il s'agit par exemple de + +* Réponse aux questions +* Raisonnement +* Traduction +* Génération de texte +* ... + +**b) Tâche** + +Une tâche constitue une forme plus granulaire d'un scénario. Elle conditionne plus spécifiquement sur quelle base le LLM +est évalué. Une tâche peut être une composition de plusieurs sous-tâches. + +* **Combinaisons de sous-tâches de difficulté variée** + +Par exemple, l'arithmétique peut être considérée comme une tâche constituée des sous-tâches arithmétique niveau 1er degré, +arithmétique niveau collège, arithmétique niveau lycée, etc. + +* **Combinaison de sous-tâche de domaines variés** + +La tâche de type QCM peut être vue comme la combinaison de QCM histoire, QCM anglais, QCM logique, etc. + + +**c) Métrique** + +Une métrique est une mesure qualitative utilisée pour évaluer la performance d'un modèle de langage dans certaines +tâches/scénarios. Une métrique peut être : + +* une fonction statistique/mathématique déterministe simple (par exemple, précision ou rappel) +* un score produit par un réseau neuronal ou un modèle de Machine Learning (ex. : score BERT) +* un score généré à l'aide d'un LLM (ex. : G-Eval) + +Notons que dans le dernier cas, évaluer un LLM à l'aide d'un LLM peut donner l'impression du serpent qui se mord la +queue. Cependant, ce type de 'dépendances circulaires' existe couramment et est bien acceptée dans d'autres dommaines. +Lors d'un entretien d'embauche par exemple, l'intellect humain évalue le potentiel d'un autre être humain. + + +**d) Benchmarks** + +Les benchmarks sont des collections standardisées de tests utilisées pour évaluer les LLM sur une tâche ou un scénario +donné. On trouvera pas exemple : + +* **SQuAD** pour le scénario de réponse aux questions de l'utilisateur à partir d'extraction de parties d'un corpus (En anglais) +* **PIAF** semblable à SQuAD mais en français +* **IMDB** pour l'analyse des sentiments +* ... + +A titre d'exemple, l'image ci-dessous présente le corpus PIAF. Il est composé de paragraphes issus d'articles de Wikipedia, +et d'une liste de questions portant sur ces paragraphes. + +![](../images/piaf_example.png) + +#### 3.3 LLM Model Evaluation vs. LLM System Evaluation + + L'expression _évaluation de LLM_ peut recouvrir différentes pratiques et différents objectifs. + On doit ainsi distinguer l'**évaluations de modèles LLM** de l'**évaluations de systèmes LLM**. + Les évaluations de modèles LLM s'intéressent aux performances globales. Les entreprises/centres de recherche qui lance + leurs LLM ont besoin de quantifier leur efficacité sur un ensemble de tâches différentes. + +Il existe de nombreux benchmarks qui permettent d'illustrer les performances des modèles sur des aspects précis, comme +HellaSwag (qui évalue la capacité d'un LLM à compléter une phrase et faire preuve de bon sens), TruthfulQA (qui mesure +la véracité des réponses du modèle) et MMLU (qui mesure la capacité de compréhension et de résolution de problèmes ). + +![](../images/llm_model_eval.webp) + +(Source https://towardsdatascience.com/llm-evals-setup-and-the-metrics-that-matter-2cc27e8e35f3) + +L'évaluation de **systèmes LLM** couvre l'évaluation de tous les composants de la chaîne, pour un modèle donné. En effet, un +modèle de LLM est rarement utilisé seul. A minima, il faut lui fournir un prompt, et celui-ci aura un fort impact sur le +résultat du modèle. On pourra s'intéresser par exemple à l'effet du prompt sur la politesse de la réponse, le style, le +niveau de détail, etc. Un modèle peut également recevoir un contexte (ensemble de documents, tableaux, images...) et +son influence doit également être mesurée. On pourrait par exemple s'apercevoir que le modèle produit des résumés de +qualité quand on lui fournit des documents littéraires, mais pas des documents techniques. + +![](../images/llm_system_eval.webp) + +(Source https://towardsdatascience.com/llm-evals-setup-and-the-metrics-that-matter-2cc27e8e35f3) + +**En pratique, l'évaluation des modèles sur des benchmarks est réalisée par les grands fournisseurs de LLM (OpenAI, +Facebook, Google, etc) ou par la communauté universitaire. Ce sont les évaluations de systèmes LLM qui intéresseront la +majorité des équipes souhaitant déployer un LLM dans leur administration.** + +#### 3.4 Détails des métriques utilisées +Il n'existe pas de réponse simple à la question de savoir quelles métriques utiliser pour évaluer son système LLM. Cela +dépendra du type de tâche, de la population cible, de la nature des données, des ressources materielles disponibles, etc +Traditionnellement, dans le domaine de l'apprentissage machine, on évalue un modèle en se dotant d'un ensemble annoté +d'entrées/sorties attendues, et on compare ensuite la distance entre la sortie obtenue et la sortie attendue. Dans le +cas de la classification, on peut par exemple mesurer le taux de bonnes réponses. + +La difficulté de l'évaluation en IA générative réside dans le fait que nous ne disposons généralement pas de valeur de +référence à laquelle comparer la sortie du modèle. Même dans les cas où l'on disposerait d'un exemple de bonne réponse, +les données de sortie étant non structurées (texte en language naturel), il est difficile de comparer la distance entre +deux objets. + +On reprend ici l'idée de classer les métriques en fonction de leur approche du problème, c'est à dire comment elles +évaluent la pertinence de la réponse obtenue. Certaines techniques supposent que l'on dispose d'une réponse de référence, +et la question est alors de savoir comment elles évaluent la distance entre la réponse obtenue et une réponse de référence. +D'autres techniques plus récentes ne font pas cette hypothèse, et cherchent à évaluer la qualité de la réponse dans +l'absolu. +![](../images/metrics_cartographie.webp) + + +On ne détaillera pas toutes les métriques dans le cadre de ce guide, il existe pléthore de documentation disponible sur +le sujet. L'objectif ici est plutôt de fournir une grille d'analyse. + +Dans les métriques classiques, on trouve des métriques générales de classification qui sont couramment utilisées en +apprentissage machine et ne sont pas propres aux données textuelles (Accuracy, Precision, Recall, F1...). Parmi les +classiques, il existe également des métriques spécifiques au texte, qui reposent sur le principe du recouvrement maximal +entre les phrases prédites et les phrases de référence. Le recouvrement peut être calculé au niveau des mots, ou au +niveau des lettres. Ces méthodes ont été critiquées par leur faible corrélation avec le jugement humain, ce qui est n'est +pas étonnant dans la mesure où elles ne s'intéressent qu'a la forme de surface des mots. + + +Les métriques basées sur le Deep Learning permettent de palier ce problème. Quand vient l'heure de choisir une métrique, +on distingue en premier lieu les métriques qui ont besoin d'une valeur de référence et les autres. Détenir une valeur de +référence peut représenter une grosse contrainte, et n'est pas toujours pertinent. Si on demande au LLM d'écrire un +poème sur la mer par exemple, il serait vain de chercher à le comparer à un autre poème. Toujours est-il que si l'on +dispose de valeurs de références, on peut recourir à des métriques basés sur les embeddings ou des métriques basées sur +des modèles fine-tunés. Les métriques qui calculent la distance entre embeddings sont parmi les moins fines, mais leur +faible complexité peut les rendre intéressantes. + + a. Métriques (biais, hallucinations, ...) + + b. Datasets + + c. Librairies/Frameworks (CODE!) + + d. Méthodologie (arbre de décision pour le décideur) diff --git a/III-Deploiements/1_Socle_minimal.qmd b/III-Deploiements/1_Socle_minimal.qmd new file mode 100644 index 0000000..48c8087 --- /dev/null +++ b/III-Deploiements/1_Socle_minimal.qmd @@ -0,0 +1,366 @@ +# PARTIE III. Deploiements + +## 1. Socle minimal pour un LLM (Camille Jérôme Conrad) + +Pour déployer un grand modèle de langage (LLM) dans une infrastructure, il est essentiel de comprendre comment requêter le modèle, les quelques couches techniques immédiates qui l'entourent et les solutions disponibles pour un déploiement efficace. + +### A. Ce dont vous avez besoin pour mettre à disposition un LLM + +Lorsqu'il s'agit de mettre en service des applications basées sur des LLM, il y a 2 composants principaux : le moteur et le serveur. Le moteur gère tout ce qui concerne les modèles et le regroupement des demandes, tandis que le serveur gère l'acheminement des demandes des utilisateurs. + +#### Moteurs + +Les moteurs sont les composants exécutant les modèles et tout ce que nous avons couvert jusqu'à présent sur le processus de génération avec différents types d'optimisations. À leur cœur, ce sont des bibliothèques Python. Ils gèrent le regroupement des demandes qui proviennent des utilisateurs vers notre chatbot et génèrent la réponse à ces demandes. + +#### Serveurs + +Les serveurs sont responsables de l'orchestration des requêtes HTTP/gRPC entrantes des utilisateurs. Dans les applications du monde réel, nous aurons de nombreux utilisateurs qui posent des questions à notre chatbot à différents moments de la journée. Les serveurs mettent ces demandes en file d'attente et les transfèrent vers le moteur pour la génération de la réponse. Les serveurs apportent également les métriques telles que le débit et la latence, qui sont importantes à suivre pour le service de modèle. + +#### Résumé + +Moteurs + +* Optimisation de la mémoire +* Optimisation spécifique au modèle +* Prise en charge du regroupement + +Serveurs + +* API HTTP/gRPC +* Mise en file d'attente des demandes +* Mise en service de plusieurs modèles +* Prise en charge de plusieurs moteurs + +### B. Exemples d'outils de mise à disposition de LLM + +Quels outils sont les mieux adaptés à nos besoins ? Comment choisir ? Voici un survol rapide de grands noms du milieu pour références. + +> Une recommandation de framework rapide à prendre en main et dont l'utilité a déjà été prouvée dans une de nos administrations se trouve à la fin et est développée dans le prochain paragraphe. + +**Moteurs** + +- TensorRT-LLM est une bibliothèque open-source qui optimise les performances d'inférence des grands modèles de langage (LLM) en utilisant les GPU NVIDIA Tensor Core. Elle utilise le parallélisme tensoriel, propose une API Python simple et comprend des versions optimisées de LLM populaires. Elle prend en charge le batching en vol et vise à simplifier la construction et l'expérimentation de nouveaux LLM. Cependant, les utilisateurs doivent spécifier la longueur d'entrée/sortie maximale et la taille de lot avant de construire le moteur, et la gestion de la mémoire du cache KV n'est pas open source. + +- vLLM est une bibliothèque à hautes performances pour l'inférence et le service LLM, axée sur le débit de service et l'efficacité mémoire grâce à son mécanisme PagedAttention. Il prend en charge le batching continu, le parallélisme GPU et la sortie en streaming, ainsi que la compatibilité OpenAI. Cependant, la mémoire peut devenir un goulot d'étranglement avec des taux de demande élevés et de grandes tailles de lot. + +**Serveurs** + +- RayLLM avec RayServe est construit sur un framework de calcul distribué qui simplifie le développement et le déploiement de modèles d'IA à grande échelle. Il prend en charge les points de terminaison multi-modèles, les fonctionnalités serveur et les optimisations via les intégrations avec vLLM et TGI. + +- Triton avec TensorRT-LLM fournit un logiciel d'inférence de serveur pour le déploiement et l'exécution efficaces de LLM avec des techniques telles que le batching en vol et le cache KV paginé. + +**Moteurs et serveurs** + +- Génération de texte Inférence (TGI) est un serveur Rust, Python et gRPC utilisé chez HuggingFace pour HuggingChat, l'API d'inférence et le point de terminaison d'inférence. Il prend en charge le batching continu, le parallélisme tensoriel, la quantification, les mécanismes d'attention, le recuit simulé des logits et des LLM spécifiques. Cependant, la licence d'utilisation a été modifiée et n'est pas gratuite pour une utilisation commerciale. + +- Enfin, Fastchat est une solution auto-hébergée pour héberger des modèles d'IA génératifs et qui propose la gestion des modèles, des API OpenAI-compatibles et une web interface simple. + +> Nous allons développer FastChat dans la partie suivante car c'est un outil qui a été testé et qui semble fournir beaucoup des éléments nécessaires pour une utilisation de première intention. + +### C. Le choix d'une solution technique : le cas d'une administration + +#### Premier cas : Les traitements par batch + +Pour certains cas d'usage, l'enjeu est de traiter de nombreuses données avec le même mode opératoire en un coup de manière ponctuelle. C'est ce qu'on appellera le traitement par batch. Cela consiste à charger un modèle, le requêter sur un tableau de prompt et obtenir la sortie pour pouvoir l'exporter. On peut le faire avec vLLM par exemple avec un morceau de code de ce type : + +```bash +from vllm import LLM, SamplingParams +import re +import pandas as pd +import re +import json +from tqdm import tqdm +from transformers import AutoTokenizer + + +list_data = json.load(open("Data.json")) + +list_prompts = [ v for x,v in list_data.items()] +list_ids = [ x for x,v in list_data.items() ] + +sampling_params = SamplingParams(temperature=0.1, top_p=0.1, max_tokens=4096) +llm = LLM(model="/data/models/hub/models--upstage--Llama-2-70b-instruct-v2/snapshots/36b2a974642846b40fbbafaabad936cd6f8a7632", tensor_parallel_size=2) +print("STARTING INFERENCE") +outputs = llm.generate(list_prompts, sampling_params) + +resume = { idx:output.outputs[0].text for idx, output in zip(list_ids, outputs) } + +json.dump(resume, open("Sortie.json", "w")) +``` + +Mais cette méthodologie a des limites, car cela nécessite de bloquer des gpus, ce qui entraîne des problématiques de gestion et de partage. + +#### Deuxième cas : Beaucoup d'utilisateurs et/ou d'applications différents + +Que ce soit une équipe de plusieurs data-scientists, ou un ensemble d'application, si les besoins sont importants, les GPUs ont tout intérêt à être partagés. Il ne sera donc pas possible que chaque script python charge son modèle en mémoire et bloque des GPUs. Il est également plus rassurant de séparer l'infrastructure GPU des utilisateurs pour que chacun travaille dans son environnement, afin d'éviter les casses accidentelles. + +La solution qui consiste à mettre à disposition des APIs vient répondre à ces problématiques. Les modèles sont cachés derrière les API, les datascientist et les applications peuvent venir les requêter et n'ont pas besoin de s'occuper de l'infrastructure. Ainsi, plutôt que chaque datascientist déploie un même modèle avec réservation de GPU, l'architecture en API permet la mise en commun du déploiement au même besoin. + +> Dans ce guide, FastChat est présenté comme exemple pour la simplicité mais d'autres solutions existent, avec chacunes leurs avantages et inconvénients. + +### D. FastChat + +FastChat propose des API OpenAI-compatibles pour ses modèles pris en charge, de sorte que vous puissiez utiliser FastChat comme une alternative locale aux API OpenAI. Cela permet d'utiliser la bibliothèque openai-python et les commandes cURL, ce qui facilite le travail des datascientists. + +La documentation complète est disponible sur le repo du module : https://github.com/lm-sys/FastChat/tree/main + +Nous allons tout de même parcourir les grandes étapes pour pouvoir lancer son installation et ensuite l'utiliser. + +#### RESTful API Server + +Tout repose sur la complémentarité de trois services : le controller, les modèles et l'API. Il faut commencer par lancer le controller. + +```bash +python3 -m fastchat.serve.controller +``` + +Ensuite, les model_workers. (Un modèle vicuna est pris pour l'exemple.) + +```bash +python3 -m fastchat.serve.model_worker --model-path lmsys/vicuna-7b-v1.5 +``` + +Et enfin, l'API. + +```bash +python3 -m fastchat.serve.openai_api_server --host localhost --port 8000 +``` + +#### Utilisation avec l'OpenAI Official SDK + +Le but de `openai_api_server.py` est d'implémenter un serveur d'API entièrement compatible avec OpenAI, de sorte que les modèles puissent être utilisés directement avec la bibliothèque openai-python. + +Tout d'abord, installez le package Python OpenAI >= 1.0 : + +```bash +pip install --upgrade openai +``` + +Ensuite, interagissez avec le modèle Vicuna : + +```python +import openai + +openai.api_key = "EMPTY" +openai.base_url = "http://localhost:8000/v1/" + +model = "vicuna-7b-v1.5" +prompt = "Il était une fois" + +# créer une complétion +completion = openai.completions.create(model=model, prompt=prompt, max_tokens=64) +# imprimer la complétion +print(prompt + completion.choices[0].text) + +# créer une complétion de chat +completion = openai.chat.completions.create( + model=model, + messages=[{"role": "user", "content": "Bonjour ! Quel est votre nom ?"}] +) +# imprimer la complétion +print(completion.choices[0].message.content) +``` + +#### Utilisation avec cURL + +cURL est un autre bon outil pour observer la sortie de l'API. + +List Models: + +```bash +curl http://localhost:8000/v1/models +``` + +Chat Completions: + +```bash +curl http://localhost:8000/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "vicuna-7b-v1.5", + "messages": [{"role": "user", "content": "Hello! What is your name?"}] + }' +``` + +Text Completions: + +```bash +curl http://localhost:8000/v1/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "vicuna-7b-v1.5", + "prompt": "Once upon a time", + "max_tokens": 41, + "temperature": 0.5 + }' +``` + +Embeddings: + +```bash +curl http://localhost:8000/v1/embeddings \ + -H "Content-Type: application/json" \ + -d '{ + "model": "vicuna-7b-v1.5", + "input": "Hello world!" + }' +``` + +#### Combiner avec vLLM + +Vous pouvez utiliser vLLM comme une mise en œuvre optimisée d'un travailleur dans FastChat. Il offre une mise en batch continue avancée et un débit beaucoup plus élevé (~10x). Consultez la liste des modèles pris en charge ici : https://docs.vllm.ai/en/latest/models/supported_models.html + +Il suffit de remplacer le model_worker par le vllm_worker + +```bash +python3 -m fastchat.serve.vllm_worker --model-path lmsys/vicuna-7b-v1.5 +``` + +#### Combiner avec Docker + +Pour permettre le lancement et l'arrêt de modèles, et pour éviter qu'une erreur dans un des modèles ne déregle l'ensemble du système, une bonne pratique est souvent de conteneuriser les différentes parties. Cela necessite la préparation de quelques fichiers et quelques tests, mais ensuite, cela assure la reproductibilité de votre infrastructure. Une fois que les images sont préparées, on peut les arrêter, les relancer et les reproduire autant de fois que nécessaire. + +Une façon d'implémenter vos services avec FastChat est de faire : + +* Un conteneur pour le controller +* Un conteneur pour l'API OpenAI like +* Un conteneur par modèle + +Les conteneurs pourront tous avoir la même image de base où l'on a installé les packages necessaires, comme vllm et notamment FastChat, que l'on a téléchargé et copié dans notre arbre local : + +Dockerfile : + +```bash +FROM nvidia/cuda:12.2.0-devel-ubuntu20.04 +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update -y && apt-get install -y python3.9 python3.9-distutils curl +RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py +RUN python3.9 get-pip.py +# Copiez le répertoire FastChat dans le conteneur Docker +COPY ./FastChat_k /FastChat +# COPY ./models/Mixtral-8x7B-Instruct-v0.1 /data/models/vllm/Mixtral-8x7B-Instruct-v0.1 +# Allez dans le répertoire FastChat et installez à partir de ce répertoire +WORKDIR /FastChat +RUN pip3 install -e ".[model_worker]" pydantic==1.10.13 +RUN pip3 install plotly==5.18.0 +RUN pip3 install accelerate==0.25.0 +RUN pip3 install vllm==0.4.1 +RUN pip3 install minio==7.2.2 +RUN pip3 install pynvml==11.5.0 + +# nvidia/cuda:12.2.0-runtime-ubuntu20.04 docker pull nvidia/cuda:12.2.0-devel-ubuntu20.04 +``` + +Ensuite, il faut lancer les conteneurs docker avec la bonne commande pour que chaque docker remplisse bien sa fonction. Cela se gère avec des docker_compose.yml + +Le fichier de déploiement des deux conteneurs obligatoires ressemblera à cela : + +```bash +version: "3.9" +services: + fastchat-controller: + build: + context: . + dockerfile: Dockerfile + image: llm-api-light:1.0.0 + network_mode: "host" + environment: + no_proxy: localhost,127.0.0.1,0.0.0.0 + ports: + - "21001:21001" + volumes: + - ./FastChat:/FastChat + entrypoint: ["python3.9", "-m", "fastchat.serve.controller", "--host", "0.0.0.0", "--port", "21001"] + fastchat-openai: + build: + context: . + dockerfile: Dockerfile + image: llm-api-light:1.0.0 + network_mode: "host" + environment: + no_proxy: localhost,127.0.0.1,0.0.0.0 + ports: + - "8000:8000" + volumes: + - ./FastChat:/FastChat + entrypoint: ["python3.9", "-m", "fastchat.serve.openai_api_server", "--host", "0.0.0.0", "--port", "8000", "--api-keys", "key1,key2,key3", "--controller-address", "http://0.0.0.0:21001"] +``` + +Et le fichier de déploiement d'un modèle pourrait ressembler à ceci : + +```bash +version: "3.9" +services: + fastchat-model-mixtral-latest: + network_mode: "host" + build: + context: . + dockerfile: Dockerfile + volumes: + - /data/models:/data/models + - ./FastChat:/FastChat + environment: + no_proxy: localhost,127.0.0.1,0.0.0.0 + TRANSFORMERS_OFFLINE: 1 + image: fastchat:cudadevel-latest + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: ["1", "5"] + capabilities: [gpu] + entrypoint: ["python3.9", "-m", "fastchat.serve.vllm_worker", "--model-path", "/data/models/vllm/Mixtral-8x7B-Instruct-v0.1", + "--worker-address", "http://0.0.0.0:26003", "--host", "0.0.0.0", "--port", "26003", "--controller", "http://0.0.0.0:21001", + "--trust-remote-code", "--model-names", "mixtral-instruct", "--num-gpus", "2"] # "--quantization", "awq" "--num-gpus", "2" +``` + +Pour finir, il suffit de lancer les commandes associées à chaque docker_compose pour lancer tous les services. Par exemple, + +```bash +# Define your Docker Compose files +compose_openai_service="docker-compose_openai.yml" +compose_mixtral="docker-compose_mistral.yml" + +# Execute Docker Compose commands +echo "Executing Docker Compose for $compose_openai_service" +docker compose -f $compose_openai_service up -d + +echo "Executing Docker Compose for $compose_mixtral" +docker compose -f $compose_mixtral up -d +``` + +A ce stade, vous avez déjà une installation utilisable par plusieurs personnes (à condition que l'url soit accessible). Voici des exemples de code de cellules notebooks. + +```python +import openai +import requests +import json +# to get proper authentication, make sure to use a valid key that's listed in +# the --api-keys flag. if no flag value is provided, the `api_key` will be ignored. +openai.api_key = "key1" # 1rentrez l'api key +openai.api_base = "host" # mettre l'url du serveur +#eventuellement régler des problèmes de proxy +``` + +```python +models = openai.Model.list() +for d in models["data"]: + print(d["id"]) +``` + +```python +# Instruct mode +prompt = """Bonjour toi. Donne moi un pays qui commence par F. +""" + +completion = openai.Completion.create( + model="mixtral?", + prompt=prompt, + max_tokens=25, + temperature=0.5, + top_p=1 +) +# print the completion +print(completion.choices[0].text) +``` diff --git a/III-Deploiements/2_Socle_avance.qmd b/III-Deploiements/2_Socle_avance.qmd new file mode 100644 index 0000000..b4f1691 --- /dev/null +++ b/III-Deploiements/2_Socle_avance.qmd @@ -0,0 +1,59 @@ +# PARTIE III. Deploiements + +## 2. Socle avancé (Camille Jérôme Conrad) + +Optimisation, Monitoring, UX/UI (CODE!) + +### A. Outils pour surveiller les performances des GPU + +Une fois l'infrastructure sécurisée, il est toujours utile de monitorer les performances des GPU, pour suivre l'impact de cette technologie, pour monitorer la charge et prévenir de la surcharge. Idéallement, l'on peut aussi imaginer suivre la consommation projet par projet pour reporter les lignes de budget et faire des bilans carbonne. + +Selon les technologies de GPUs utilisées, il existe différents outils qui se conncectent aux infrastructure pour fournir des statistiques (notamment la mémoire utilisée, la bande passante et la température) : + +* **nvidia-smi** +* **AMD Vantage** +* **GPU-Z** + +Voici un exemple de résultat de statistiques extraites d'une infrastructure GPUs : + +![Resultat de la commande nvidia-smi](../images/nvidia-smi.png "Resultat de la commande nvidia-smi") + +Il existe également d'autres moyens d'accéder à des GPUs que l'acquisition individuelle pour les administrations (voir Partie III.4). + +### B. Des interfaces déjà disponibles pour vos modèles LLMs + +Plusieurs initiatives permettent de déployer rapidement des interfaces de chat avec des modèles LLMs, voire des applications de RAG avec back et front. On peut remarquer : + +- la WebUI du module FastChat +- l'application CARADOC, mise en open source par l'équipe DataScience de la DTNUM de la DGFiP, publication prévue pour fin juin 2024. + +Aperçu de l'application CARADOC pendant ses développements : + +![Interface de l'application RAG Caradoc](../images/chat.png "Interface de l'application RAG Caradoc") + +Aperçu d'un interface possible avec FastChat : + +![Interface de l'application Chat avec FastChat](../images/chat2.png "Interface de l'application Chat avec FastChat") + +Exemple de code pour lancer l'interface Gradio de FastChat dans un Docker : + +```bash +version: "3.9" +services: + fastchat-gradio-server: + network_mode: "host" + build: + context: . + dockerfile: Dockerfile + environment: + FASTCHAT_CONTROLLER_URL: http://0.0.0.0:21001 + no_proxy: localhost,127.0.0.1,0.0.0.0 + image: fastchat:latest + ports: + - "8001:8001" + volumes: + - ./FastChat:/FastChat + entrypoint: ["python3.9", "-m", "fastchat.serve.gradio_web_server_dtnum", "--controller-url", "http://0.0.0.0:21001", "--host", "0.0.0.0", "--port", "8001", "--model-list-mode", "reload"] +``` + +Avec toujours l'image Docker qui contient FastChat. diff --git a/III-Deploiements/3_Socle_Production.qmd b/III-Deploiements/3_Socle_Production.qmd new file mode 100644 index 0000000..1134c93 --- /dev/null +++ b/III-Deploiements/3_Socle_Production.qmd @@ -0,0 +1,290 @@ +# PARTIE III. Deploiements + +## 3. Socle pour production (Camille Jérôme Conrad) + +Les LLM sont des modèles de langage puissants qui nécessitent des ressources informatiques importantes pour fonctionner efficacement. Pour mettre en production une application utilisant des LLM, il est essentiel de choisir le bon matériel et les bons outils pour garantir la disponibilité des applications et des performances optimales. + +Pour certains modèles de langage, les processeurs habituels appelés CPU (Central Processing Unit) peuvent suffire. Mais pour la plupart des modèles plus importants, pour que les calculs se fassent dans des temps raisonnables, il est nécessaire de se doter d'unités de traitement graphique (GPU). Nous allons donc nous intéresser ici aux différents critères à étudier pour choisir correctement des GPUs, aux outils qui permettent de suivre leurs performances et enfin le lien avec les essentiels de déploiements en termes de management de ressources (avec l'exemple du lien à Kubernetes). + +### A. GPU pour les LLM + +La sélection des GPU (Graphics Processing Units) pour une installation dans une structure dépend de multiples facteurs. En voici quelques uns : + +1. **Puissance de calcul** : La puissance de traitement des GPU est mesurée en flops (floating-point operations per second). Un GPU plus puissant permettra d'exécuter des tâches plus rapidement et de gérer des charges de travail plus élevées. +2. **Mémoire vive** : La mémoire vive (VRAM) des GPU est essentielle pour les applications nécessitant une grande quantité de mémoire, comme les simulations scientifiques ou les applications de traitement d'image. Assurez-vous de choisir des GPU avec suffisamment de mémoire vive pour répondre aux besoins de vos applications. +3. **Énergie et consommation** : Les GPU consomment de l'énergie et génèrent de la chaleur. Choisissez des GPU économes en énergie et dotés de systèmes de refroidissement efficaces pour réduire les coûts énergétiques et améliorer la durée de vie des composants. +4. **Coût et rentabilité** : Évaluez le coût total de possession (TCO) des GPU, en tenant compte des coûts d'achat, de maintenance et d'énergie. Choisissez des GPU qui offrent une bonne rentabilité pour votre administration. +5. **Compatibilité avec les systèmes d'exploitation** : Vérifiez que les GPU sont compatibles avec les systèmes d'exploitation utilisés dans votre administration, tels que Windows, Linux ou macOS. + +Pour le dernier point, il est commun d'acheter les GPUs par plusieurs, déjà groupés dans des serveurs. Il faut faire attention cependant au format et aux besoins spécifiques de ces serveurs, qui ne sont souvent pas standards par leur taille et par la chaleur qu'ils dégagent. + +Des GPUs reconnus peuvent être les T5, A100, V100 et leur prix d'achat est de l'ordre de milliers d'euros, mais il faut bien prendre en compte également les coûts cachés. En effet, l'intégration dans un SI pré-existant peut nécessiter des travaux. Durant leur cycle de vie, ils ont besoin de maintenance. Et enfin, tout au long de leur utilisation, ils ont besoin d'être administrés, ce qui peut représenter des Equivalents Temps Plein (ETP), dont le coût n'est pas à négliger. + +### B. Orchestration avec des GPUs + +Il est judicieux d'utiliser un orchestrateur pour déployer des Language Models (LLMs) dans une organisation pour plusieurs raisons : + +1. Simplification de la gestion des déploiements : un orchestrateur permet de gérer de manière centralisée tous les déploiements de LLMs dans l'organisation. Cela facilite la surveillance, la maintenance et la mise à l'échelle des déploiements. +2. Évolutivité : un orchestrateur permet de mettre à l'échelle automatiquement les déploiements en fonction de la demande, ce qui est particulièrement utile pour les LLMs qui peuvent être très gourmands en ressources. +3. Sécurité : un orchestrateur peut aider à renforcer la sécurité en fournissant des fonctionnalités telles que l'authentification, l'autorisation et le chiffrement des données. Il peut également aider à respecter les normes de conformité en matière de traitement des données. +4. Gestion des versions : un orchestrateur permet de gérer les versions des LLMs et de faciliter le déploiement de nouvelles versions ou de rollbacks en cas de problème. +5. Intégration avec d'autres outils : un orchestrateur peut s'intégrer facilement avec d'autres outils de développement et d'exploitation, tels que les systèmes de surveillance, les outils de débogage et les systèmes de journalisation. +6. Réduction des coûts : en automatisant les déploiements et en les mettant à l'échelle de manière efficace, un orchestrateur peut aider à réduire les coûts associés aux déploiements de LLMs. + +En résumé, un orchestrateur offre une gestion centralisée, une évolutivité, une sécurité renforcée, une gestion des versions, une intégration avec d'autres outils et une réduction des coûts pour les déploiements de LLMs dans une organisation. Des solutions techniques peuvent être : + +* **Kubernetes** +* **Docker Swarm** +* **Apache Mesos** + +### C. Exemple de déploiement + +Nous allons développer dans cette partie un exemple de déploiement d'une structure LLM avec Kubernetes. On utilise la même structure de microservices que dans la partie précedente avec FastChat mais cela peut être adapté à tout choix d'organisation et d'architecture. + +Voici un schéma résumant l'organisation proposée ici, avec le controller, l'api openai-like et deux modèles LLMs : + +![Schéma de structure des services pour Kubernetes](../images/kube.png "Schéma de structure des services pour Kubernetes") + +La méthodologie générale de l'utilisation de Kubernetes est la suivante : + +1. Préparer les images Docker qui seront utilisées pour les déploiements +2. Créez les fichiers de configuration YAML pour votre application +3. Déployez les avec : +```bash +kubectl apply -f FILENAMES.yaml +``` +4. Surveiller le lancement des différents services et leur bonne interconnexion + +Avec cela, vous avez une application plus robuste, mais cela necessite une certaine familiarité avec Kubernetes. Quelques exemples de fichiers de configuration sont proposés ci-dessous. + +1. Tout d'abord les services obligatoires comme le gestionnaire de l'API et le controlleur. On fait en même temps le deployment du pod et le service permettant d'y accéder. Ils se basent sur une image Docker légère et sans requirements spécifiques. + +On remarquera que les deux deploiments semblent assez similaires et que la principale différence réside dans les noms donnés aux objets et à la commande lancée dans le conteneur lancé : + +```bash +["python3.9", "-m", "fastchat.serve.controller", "--host", "0.0.0.0", "--port", "21001"] +``` + +ou + +```bash +["python3.9", "-m", "fastchat.serve.openai_api_server", "--host", "0.0.0.0", "--port", "8000", "--api-keys", "key1", "--controller-address", "http://svc-controller"] +``` + +Ces commandes sont celles de FastChat mais peuvent être remplacées par votre propre solution de déploiement de modèle. + +Pour le controlleur : + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fastchat-controller +spec: + replicas: 1 + selector: + matchLabels: + app: fastchat-controller + template: + metadata: + labels: + app: fastchat-controller + spec: + containers: + - name: fastchat-controller + image: llm-api-light:1.0.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 21001 + env: + - name: no_proxy + value: localhost,127.0.0.1,0.0.0.0,svc-llm-mixtral,svc-llm-e5-dgfip,svc-llm-llama + command: ["python3.9", "-m", "fastchat.serve.controller", "--host", "0.0.0.0", "--port", "21001"] + imagePullSecrets: + - name : regcred + +--- + +apiVersion: v1 +kind: Service +metadata: + name: svc-controller2 +spec: + type: NodePort + ports: + - nodePort: 30001 + port: 80 + targetPort: 21001 + selector: + app: fastchat-controller +``` + +Et pour l'api : + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fastchat-openai +spec: + replicas: 1 + selector: + matchLabels: + app: fastchat-openai + template: + metadata: + labels: + app: fastchat-openai + spec: + containers: + - name: fastchat-openai + image: llm-api-light:1.0.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8000 + env: + - name: no_proxy + value: localhost,127.0.0.1,0.0.0.0,svc-controller,svc-llm-mixtral + command: ["python3.9", "-m", "fastchat.serve.openai_api_server", "--host", "0.0.0.0", "--port", "8000", "--api-keys", "key1", "--controller-address", "http://svc-controller"] + imagePullSecrets: + - name : regcred + +--- + +apiVersion: v1 +kind: Service +metadata: + name: svc-openai-api +spec: + type: NodePort + ports: + - nodePort: 30081 + port: 80 + targetPort: 8000 + selector: + app: fastchat-openai +``` + +2. Créez les fichiers de configuration pour un modèle LLM, avec également le pod et le service correspondant. Cette fois-ci, l'image est plus lourde car elle contient le modèle et les modules nécessaires à son fonctionnement. + +On remarquera notamment : + +```bash +image: fastchat-mixtral:v0.3.1 +``` + +```bash +resources: + limits: + nvidia.com/gpu: 2 + +``` + +Et la commande qui lance le modèle (ici Fastchat mais pourrait être n'importe quel module): + +```bash +command: ["python3", "-m", "fastchat.serve.vllm_worker", "--model-path", "/data/models/vllm/Mixtral-8x7B-Instruct-v0.1", "--worker-address", "http://svc-llm-mixtral", "--host", "0.0.0.0", "--port", "2100", "--controller", "http://svc-controller", "--trust-remote-code", "--model-names", "mixtral-instruct", "--num-gpus", "2"] +``` + +```bash +apiVersion: apps/v1 +kind: Deployment +metadata: + name: llm-mixtral +spec: + replicas: 1 + selector: + matchLabels: + app: llm-mixtral + template: + metadata: + labels: + app: llm-mixtral + spec: + containers: + - name: llm-mixtral + image: fastchat-mixtral:v0.3.1 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 2100 + env: + - name: no_proxy + value: localhost,127.0.0.1,0.0.0.0,svc-controller + - name: CUDA_VISIBLE_DEVICES + value: "0,1" + command: ["python3", "-m", "fastchat.serve.vllm_worker", "--model-path", "/data/models/vllm/Mixtral-8x7B-Instruct-v0.1", "--worker-address", "http://svc-llm-mixtral", "--host", "0.0.0.0", "--port", "2100", "--controller", "http://svc-controller", "--trust-remote-code", "--model-names", "mixtral-instruct", "--num-gpus", "2"] + resources: + limits: + nvidia.com/gpu: 2 + imagePullSecrets: + - name : regcred + +--- + +apiVersion: v1 +kind: Service +metadata: + name: svc-llm-mixtral +spec: + type: NodePort + ports: + - nodePort: 30091 + port: 80 + targetPort: 2100 + selector: + app: llm-mixtral +``` + +Enfin, tous ces composants se basent sur des images docker qui continennent tout le code de mise à disposition des modèles ou des APIs. Des exemples d'images utiles pour les différents services sus-mentionnés sont décrites dans ce Dockerfile : + +```bash +#################### BASE OPENAI IMAGE #################### +FROM python:3.9-buster as llm-api-light + +# Set environment variables +ENV DEBIAN_FRONTEND noninteractive +# Install dependencies +RUN apt-get update -y && apt-get install -y curl +# Install pip +RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py +RUN python3.9 get-pip.py +# Copy the FastChat directory into the Docker container +WORKDIR / +RUN git clone -n https://github.com/lm-sys/FastChat.git && \ + cd FastChat && \ + git checkout ed6735d +# Go into the FastChat directory and install from this directory +WORKDIR /FastChat +RUN pip3 install -e ".[webui]" pydantic==1.10.13 +RUN pip3 install plotly + +#################### BASE LLM BUILD IMAGE #################### +FROM nvidia/cuda:12.1.0-devel-ubuntu22.04 AS base +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update -y && apt-get install -y python3.9 curl +RUN apt-get install -y python3-pip git +# Copiez le répertoire FastChat dans le conteneur DockerEnfin, tous c + +WORKDIR / +RUN git clone -n https://github.com/lm-sys/FastChat.git && \ + cd FastChat && \ + git checkout ed6735d + +# Allez dans le répertoire FastChat et installez à partir de ce répertoire +WORKDIR /FastChat +RUN pip3 install --upgrade pip +RUN pip3 install -e ".[model_worker]" pydantic==1.10.13 +RUN pip3 install plotly==5.18.0 +RUN pip3 install accelerate==0.25.0 +RUN pip3 install vllm==0.3.1 +RUN pip3 install minio==7.2.2 +RUN pip3 install pynvml==11.5.0 + +#################### EXTENSION LLAMA #################### +FROM base AS llm-llama +COPY ./models/Upstage--Llama-2-70b-instruct-v2 /data/models/vllm/Upstage--Llama-2-70b-instruct-v2 + +#################### EXTENSION LLAMA #################### +FROM base AS llm-mixtral +COPY ./models/Mixtral-8x7B-Instruct-v0.1 /data/models/vllm/Mixtral-8x7B-Instruct-v0.1 +``` diff --git a/III-Deploiements/4_Infras_administrations.qmd b/III-Deploiements/4_Infras_administrations.qmd new file mode 100644 index 0000000..f3085db --- /dev/null +++ b/III-Deploiements/4_Infras_administrations.qmd @@ -0,0 +1,13 @@ +# Guide du LLM + +### PARTIE III. Deploiements + +### 4. Infras dispos pour l’administration (Thibault Katia) + + SSP Cloud (Onyxia) + + Cloud PI + + Clouds privés (SECNUMCLOUD, Sens?) + + (NuboNyxia à terme) diff --git a/README.md b/README.md index aa42438..5673c11 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,14 @@ Il est aujourd'hui difficile de savoir quel LLM est adapté pour son besoin spé | Membre | Administration | | ------ | -------------- | |Conrad THIOUNN| Dares - Ministère du Travail | -| Johnny PLATON | | Santé publique France +| Johnny PLATON | Santé publique France | | Thibault DUROUCHOUX | | -| Katia JODOGNE-DEL LITTO | | +| Katia JODOGNE-DEL LITTO | IGF - Ministère de l'Economie et des Finances | | Faheem BEG | | | Camille ANDRÉ| | | Camille BRIER | DTNum - DGFiP | | Daphné PERTSEKOS | ANFSI - Ministère de l'intérieur| +| Zhanna SANTYBAYEVA | DGOS - Ministère du travail, de la santé et des solidarités| ## Épilogue diff --git a/_quarto.yaml b/_quarto.yaml new file mode 100644 index 0000000..0b9eb47 --- /dev/null +++ b/_quarto.yaml @@ -0,0 +1,54 @@ +project: + type: website + +execute: + freeze: auto + +website: + title: "Guide d'installation des LLM" + + page-footer: + right: "Ce site a été créé avec [Quarto](https://quarto.org/)" + + sidebar: + pinned: true + align: center + style: "docked" + contents: + - section: "I-Accompagnement" + contents: + - href: I-Accompagnement/1_Besoins.qmd + text: "Besoins" + - href: I-Accompagnement/2_Deja_Fait_Admin.qmd + text: "Exemples dans l'administration" + - href: I-Accompagnement/3_Acculturation.qmd + text: "Acculturation" + - href: I-Accompagnement/4_Impacts.qmd + text: "Impacts" + - section: "II-Developpements" + contents: + - href: II-Developpements/1_Revue_Technique_LLM.qmd + text: "Revue technique des LLM" + - href: II-Developpements/2_RAG.qmd + text: "Retrieval Augmented Generation" + - href: II-Developpements/3_Evaluations.qmd + text: "Evaluations" + - section: "III-Deploiements" + contents: + - href: III-Deploiements/1_Socle_minimal.qmd + text: "Socle minimal" + - href: III-Deploiements/2_Socle_avance.qmd + text: "Socle avancé" + - href: III-Deploiements/3_Socle_Production.qmd + text: "Socle Production" + - href: III-Deploiements/4_Infras_administrations.qmd + text: "Infrastructures dans l'administration" + +format: + html: + theme: + light: flatly + dark: darkly + code-copy: true + code-overflow: wrap + toc: true \ No newline at end of file diff --git a/images/chat.png b/images/chat.png new file mode 100644 index 0000000..55a90da Binary files /dev/null and b/images/chat.png differ diff --git a/images/chat2.png b/images/chat2.png new file mode 100644 index 0000000..c35d40a Binary files /dev/null and b/images/chat2.png differ diff --git a/images/kube.png b/images/kube.png new file mode 100644 index 0000000..6f23528 Binary files /dev/null and b/images/kube.png differ diff --git a/images/llm_model_eval.webp b/images/llm_model_eval.webp new file mode 100644 index 0000000..c02db4b Binary files /dev/null and b/images/llm_model_eval.webp differ diff --git a/images/llm_system_eval.webp b/images/llm_system_eval.webp new file mode 100644 index 0000000..cf83568 Binary files /dev/null and b/images/llm_system_eval.webp differ diff --git a/images/metrics_cartographie.webp b/images/metrics_cartographie.webp new file mode 100644 index 0000000..5906522 Binary files /dev/null and b/images/metrics_cartographie.webp differ diff --git a/images/nvidia-smi.png b/images/nvidia-smi.png new file mode 100644 index 0000000..d943e47 Binary files /dev/null and b/images/nvidia-smi.png differ diff --git a/images/piaf_example.png b/images/piaf_example.png new file mode 100644 index 0000000..95303a0 Binary files /dev/null and b/images/piaf_example.png differ diff --git "a/ressources/Infra LLM \303\240 la DTNum.pptx" "b/ressources/Infra LLM \303\240 la DTNum.pptx" new file mode 100644 index 0000000..a19228d Binary files /dev/null and "b/ressources/Infra LLM \303\240 la DTNum.pptx" differ diff --git a/ressources/Learning_lunch_LLM_p1.pptx b/ressources/Learning_lunch_LLM_p1.pptx new file mode 100644 index 0000000..55d59ba Binary files /dev/null and b/ressources/Learning_lunch_LLM_p1.pptx differ diff --git a/ressources/Learning_lunch_LLM_p2.pptx b/ressources/Learning_lunch_LLM_p2.pptx new file mode 100644 index 0000000..952b95f Binary files /dev/null and b/ressources/Learning_lunch_LLM_p2.pptx differ