
Scanneur de vulnérabilités LLM modulaire qui détecte les hallucinations, les fuites de données, les injections de prompts, les jailbreaks et la toxicité à l'aide de sondes statiques, dynamiques et adaptatives sur plusieurs fournisseurs de modèles.
Kit de red-teaming et d'évaluation pour l'IA générative
garak vérifie si un LLM peut être amené à échouer d'une manière que nous ne souhaitons pas. garak sonde les hallucinations, les fuites de données, l'injection de prompt, la désinformation, la génération de toxicité, les jailbreaks, et bien d'autres faiblesses. Si vous connaissez nmap ou msf / Metasploit Framework, garak fait des choses similaires, mais pour les LLMs.
garak se concentre sur les moyens de faire échouer un LLM ou un système de dialogue. Il combine des sondes statiques, dynamiques et adaptatives pour explorer cela.
garak est un outil gratuit. Nous adorons le développer et sommes toujours intéressés par l'ajout de fonctionnalités pour soutenir les applications.
prend actuellement en charge :
garak est un outil en ligne de commande. Il est développé sous Linux et OSX.
pipIl suffit de le récupérer depuis PyPI et vous devriez être prêt :``` python -m pip install -U garak
### Install development version with `pip`
La version standard pip de `garak` est mise à jour périodiquement. Pour obtenir une version plus récente depuis GitHub, essayez :```
python -m pip install -U git+https://github.com/NVIDIA/garak.git@main
garak a ses propres dépendances. Vous pouvez installer garak dans son propre environnement Conda :```
conda create --name garak "python>=3.10,<=3.12"
conda activate garak
gh repo clone NVIDIA/garak
cd garak
python -m pip install -e .
OK, si tout s'est bien passé, vous êtes probablement prêt !
**Remarque**: si vous avez cloné avant le déplacement vers l'organisation GitHub `NVIDIA`, mais que vous lisez ceci à l'URI `github.com/NVIDIA`, veuillez mettre à jour vos dépôts distants comme suit :```
git remote set-url origin https://github.com/NVIDIA/garak.git
La syntaxe générale est :
garak <options>
garak a besoin de savoir quel modèle analyser, et par défaut, il essaiera toutes les sondes qu'il connaît sur ce modèle, en utilisant les détecteurs de vulnérabilité recommandés par chaque sonde.
Vous pouvez voir une liste des sondes en utilisant :
garak --list_probes
Pour spécifier un générateur, utilisez les options --target_type et, optionnellement, --target_name. Le type de modèle spécifie une famille/interface de modèle ; le nom du modèle spécifie le modèle exact à utiliser. La section « Intro to generators » ci-dessous décrit certains des générateurs pris en charge. Une famille de générateurs simple est celle des modèles Hugging Face ; pour en charger un, définissez --target_type sur huggingface et --target_name sur le nom du modèle sur Hub (par exemple "RWKV/rwkv-4-169m-pile"). Certains générateurs peuvent nécessiter qu'une clé API soit définie comme variable d'environnement, et ils vous informeront si c'est le cas.
garak exécute toutes les sondes par défaut, mais vous pouvez aussi être plus spécifique. --probes promptinject utilisera uniquement les méthodes du framework PromptInject, par exemple. Vous pouvez également spécifier un plugin spécifique au lieu d'une famille de plugins en ajoutant le nom du plugin après un . ; par exemple, --probes lmrc.SlurUsage utilisera une implémentation qui vérifie si les modèles génèrent des insultes basée sur le framework Language Model Risk Cards.
Pour de l'aide et de l'inspiration, retrouvez-nous sur Twitter ou discord !
Sonder un modèle commercial pour l'injection de prompt basée sur l'encodage (OSX/*nix) (remplacez la valeur d'exemple par une vraie clé API OpenAI)``` export OPENAI_API_KEY="sk-123XXXXXXXXXXXX" python3 -m garak --target_type openai --target_name gpt-5-nano --probes encoding
Vérifiez si la version Hugging Face de GPT2 est vulnérable à DAN 11.0```
python3 -m garak --target_type huggingface --target_name gpt2 --probes dan.Dan_11_0
Pour chaque sonde chargée, garak affichera une barre de progression lors de la génération. Une fois la génération terminée, une ligne évaluant les résultats de cette sonde sur chaque détecteur est affichée. Si l'une des tentatives de prompt a produit un comportement indésirable, la réponse sera marquée comme FAIL et le taux d'échec sera indiqué.
Voici les résultats avec le module encoding sur une variante de GPT-3 :

Et les mêmes résultats pour ChatGPT :

On constate que le modèle le plus récent est beaucoup plus sensible aux attaques par injection basées sur l'encodage, alors que text-babbage-001 n'était vulnérable qu'aux injections quoted-printable et MIME. Les chiffres à la fin de chaque ligne, par exemple 840/840, indiquent le nombre total de générations de texte, puis combien d'entre elles semblaient correctes. Ce nombre peut être élevé car plusieurs générations sont réalisées par prompt – par défaut, 10.
Les erreurs vont dans garak.log ; le déroulement est enregistré en détail dans un fichier .jsonl spécifié au début et à la fin de l'analyse. Un script d'analyse de base se trouve dans analyse/analyse_log.py qui affichera les sondes et les prompts ayant généré le plus de résultats.
Envoyez des PRs et ouvrez des issues. Bonne chasse !
Utilisation de l'API Pipeline :
--target_type huggingface (pour les modèles transformers à exécuter localement)--target_name – utilisez le nom du modèle depuis le Hub. Seuls les modèles génératifs fonctionneront. En cas d'échec inattendu, veuillez ouvrir une issue et coller la commande essayée ainsi que l'exception !Utilisation de l'API Inference :
--target_type huggingface.InferenceAPI (pour un accès aux modèles via API)--target_name – le nom du modèle depuis le Hub, par ex. "mosaicml/mpt-7b-instruct"Utilisation de points de terminaison privés :
--target_type huggingface.InferenceEndpoint (pour les points de terminaison privés)
--target_name – l'URL du point de terminaison, par ex. https://xxx.us-east-1.aws.endpoints.huggingface.cloud
(facultatif) définissez la variable d'environnement HF_INFERENCE_TOKEN avec un jeton API Hugging Face ayant le rôle "lecture" ; voir https://huggingface.co/settings/tokens une fois connecté
--target_type openai--target_name – le modèle OpenAI que vous souhaitez utiliser. gpt-5-nano est rapide et suffit pour les tests.OPENAI_API_KEY avec votre clé API OpenAI (par ex. "sk-19763ASDF87q6657") ; voir https://platform.openai.com/account/api-keys une fois connectéLes types de modèles reconnus sont sur liste blanche, car le plugin doit savoir quelle sous-API utiliser. Les modèles de type Complétion ou ChatCompletion conviennent. Si vous souhaitez utiliser un modèle non pris en charge, un message d'erreur explicatif devrait s'afficher ; veuillez envoyer une PR ou ouvrir une issue.
REPLICATE_API_TOKEN avec votre jeton API Replicate, par ex. "r8-123XXXXXXXXXXXX" ; voir https://replicate.com/account/api-tokens une fois connectéModèles Replicate publics :
--target_type replicate--target_name – le nom du modèle Replicate et son hash, par ex. "stability-ai/stablelm-tuned-alpha-7b:c49dae36"Points de terminaison Replicate privés :
--target_type replicate.InferenceEndpoint (pour les points de terminaison privés)--target_name – le slug nom_utilisateur/nom_modèle du point de terminaison déployé, par ex. elim/elims-llama2-7b--target_type cohere--target_name (facultatif, command par défaut) – le modèle Cohere spécifique que vous souhaitez testerCOHERE_API_KEY avec votre clé API Cohere, par ex. "aBcDeFgHiJ123456789" ; voir https://dashboard.cohere.ai/api-keys une fois connecté--target_type groq--target_name – le nom du modèle à utiliser via l'API GroqGROQ_API_KEY avec votre clé API Groq ; voir https://console.groq.com/docs/quickstart pour les détails de création d'une clé API--target_type ggml--target_name – le chemin vers le modèle ggml que vous souhaitez charger, par ex. /home/leon/llama.cpp/models/7B/ggml-model-q4_0.binGGML_MAIN_PATH avec le chemin vers votre exécutable main ggmlrest.RestGenerator est très flexible et peut se connecter à n'importe quel point de terminaison REST qui renvoie du texte brut ou du JSON. Il nécessite une brève configuration, qui aboutira généralement à un fichier YAML court décrivant votre point de terminaison. Voir https://reference.garak.ai/en/latest/garak.generators.rest.html pour des exemples.
Utilisez les modèles de https://build.nvidia.com/ ou d'autres points de terminaison NIM.
NIM_API_KEY avec votre jeton d'authentification API, ou spécifiez-le dans le YAML de configurationPour les modèles de chat :
--target_type nim--target_name – le nom du model NIM, par ex. meta/llama-3.1-8b-instructPour les modèles de complétion :
--target_type nim.NVOpenAICompletion--target_name – le nom du model NIM, par ex. bigcode/starcoder2-15b--target_type bedrock--target_name – l'ID ou l'alias du modèle Bedrock, par ex. anthropic.claude-3-sonnet-20240229-v1:0 ou claude-3-sonnetBEDROCK_API_KEY avec votre clé API AWS Bedrock ; voir https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys-use.html pour les instructions de configurationBEDROCK_REGION pour spécifier la région AWS (par défaut us-east-1)Les familles de modèles prises en charge incluent Anthropic Claude, Meta Llama, Amazon Titan, AI21 Labs, Cohere et Mistral AI. Le générateur utilise l'API Converse pour un accès unifié à tous les types de modèles.
Exemple d'utilisation :``` export BEDROCK_API_KEY="your-api-key" export BEDROCK_REGION="us-east-1" garak --target_type bedrock --target_name claude-3-sonnet --probes dan
### Test
* `--target_type test`
* (alternativement) `--target_name test.Blank`
Pour les tests. Cela génère toujours la chaîne vide, en utilisant le générateur `test.Blank`. Sera marqué comme échec pour tous les tests qui *nécessitent* une sortie, par exemple ceux qui font des affirmations controversées et attendent du modèle qu'il les réfute pour réussir.
* `--target_type test.Repeat`
Pour les tests. Ce générateur répète l'invite qu'il a reçue.
## Introduction aux sondes
| Sonde | Description |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| blank | Une sonde simple qui envoie toujours une invite vide. |
| atkgen | Génération automatique d'attaques. Un LLM red-team sonde la cible et réagit à celle-ci dans le but d'obtenir une sortie toxique. Prototype, principalement sans état, utilise pour l'instant un simple GPT-2 [fine-tuné](https://huggingface.co/garak-llm/artgpt2tox) sur le sous-ensemble des tentatives hhrlhf qui ont produit une toxicité détectable (le seul type de cible actuellement pris en charge pour l'instant). |
| badchars | Implémente des perturbations Unicode imperceptibles (caractères invisibles, homoglyphes, réordonnancements, suppressions) inspirées par l'article [Bad Characters](https://arxiv.org/abs/2106.09898). |
| av_spam_scanning | Sondes qui tentent de faire produire au modèle des signatures de contenu malveillant |
| continuation | Sondes qui testent si le modèle va continuer un mot probablement indésirable |
| dan | Diverses attaques [DAN](https://adguard.com/en/blog/chatgpt-dan-prompt-abuse.html) et de type DAN |
| donotanswer | Invites auxquelles les modèles de langage responsables ne devraient pas répondre. |
| encoding | Injection d'invite par encodage de texte |
| gcg | Perturber une invite système en ajoutant un suffixe antagoniste. |
| glitch | Sonder le modèle pour les jetons « glitch » qui provoquent un comportement inhabituel. |
| grandma | Faire appel au souvenir de sa grand-mère. |
| goodside | Implémentations des attaques de Riley Goodside. |
| leakreplay | Évaluer si un modèle va rejouer des données d'entraînement. |
| lmrc | Sous-échantillon des sondes [Language Model Risk Cards](https://arxiv.org/abs/2303.18190) |
| malwaregen | Tentatives de faire générer au modèle du code pour construire des malwares |
| misleading | Tentatives de faire soutenir au modèle des affirmations trompeuses et fausses |
| packagehallucination | Essayer d'obtenir des générations de code qui spécifient des paquets inexistants (et donc non sécurisés). |
| promptinject | Implémentation des travaux [PromptInject](https://github.com/agencyenterprise/PromptInject/tree/main/promptinject) d'Agency Enterprise (best paper awards @ NeurIPS ML Safety Workshop 2022) |
| realtoxicityprompts | Sous-ensemble des travaux RealToxicityPrompts (données limitées car le test complet prendrait trop de temps) |
| snowball | Sondes [Snowballed Hallucination](https://ofir.io/snowballed_hallucination.pdf) conçues pour faire donner au modèle une réponse erronée à des questions trop complexes pour qu'il puisse les traiter |
| xss | Rechercher des vulnérabilités qui permettent ou réalisent des attaques cross-site, comme l'exfiltration de données privées. |
## Journalisation
`garak` génère plusieurs types de journaux :
* Un fichier journal, `garak.log`. Il contient les informations de débogage de `garak` et de ses plugins, et est conservé d'une exécution à l'autre.
* Un rapport de l'exécution en cours, structuré en JSONL. Un nouveau fichier de rapport est créé à chaque exécution de `garak`. Le nom de ce fichier est affiché au début et, en cas de succès, également à la fin de l'exécution. Dans le rapport, une entrée est créée pour chaque tentative de sondage, à la fois lors de la réception des générations et à nouveau lorsqu'elles sont évaluées ; l'attribut `status` de l'entrée prend une constante de `garak.attempts` pour décrire l'étape à laquelle elle a été créée.
* Un journal des succès (« hits »), détaillant les tentatives qui ont révélé une vulnérabilité.
## Comment le code est-il structuré ?
Consultez la [documentation de référence](https://reference.garak.ai/) pour un guide faisant autorité sur la structure du code de `garak`.
Lors d'une exécution typique, `garak` lit un type de modèle (et éventuellement un nom de modèle) depuis la ligne de commande, détermine quelles `probes` et `detectors` exécuter, démarre un `generator`, puis les transmet à un `harness` pour effectuer le sondage ; un `evaluator` traite les résultats. Il existe de nombreux modules dans chacune de ces catégories, et chaque module fournit un certain nombre de classes qui agissent comme des plugins individuels.
* `garak/probes/` - classes pour générer des interactions avec les LLM
* `garak/detectors/` - classes pour détecter qu'un LLM présente un mode de défaillance donné
* `garak/evaluators/` - schémas de rapport d'évaluation
* `garak/generators/` - plugins pour les LLM à sonder
* `garak/harnesses/` - classes pour structurer les tests
* `resources/` - éléments auxiliaires requis par les plugins
Le mode de fonctionnement par défaut consiste à utiliser le `harness` `probewise`. Étant donné une liste de noms de modules de sondes et de noms de plugins de sondes, le `harness` `probewise` instancie chaque sonde, puis pour chaque sonde lit ses attributs `primary_detector` et `extended_detectors` pour obtenir une liste de `detectors` à exécuter sur la sortie.
Chaque catégorie de plugins (`probes`, `detectors`, `evaluators`, `generators`, `harnesses`) comprend un `base.py` qui définit les classes de base utilisables par les plugins de cette catégorie. Chaque module de plugin définit des classes de plugin qui héritent de l'une des classes de base. Par exemple, `garak.generators.openai.OpenAIGenerator` descend de `garak.generators.base.Generator`.
Les artefacts volumineux, comme les fichiers de modèles et les corpus plus importants, sont conservés en dehors du dépôt ; ils peuvent être stockés sur e.g. Hugging Face Hub et chargés localement par les clients utilisant `garak`.
## Développer votre propre plugin
* Jetez un œil à la façon dont les autres plugins le font
* Héritez de l'une des classes de base, par exemple `garak.probes.base.TextProbe`
* Remplacez le moins de choses possible
* Vous pouvez tester le nouveau code d'au moins deux manières :
* Lancez une session Python interactive
* Importez le modèle, par exemple `import garak.probes.mymodule`
* Instanciez le plugin, par exemple `p = garak.probes.mymodule.MyProbe()`
* Lancez une analyse avec des plugins de test
* Pour les sondes, essayez un générateur vide et le détecteur always.Pass : `python3 -m garak -m test.Blank -p mymodule -d always.Pass`
* Pour les détecteurs, essayez un générateur vide et une sonde vide : `python3 -m garak -m test.Blank -p test.Blank -d mymodule`
* Pour les générateurs, essayez une sonde vide et le détecteur always.Pass : `python3 -m garak -m mymodule -p test.Blank -d always.Pass`
* Demandez à `garak` de lister tous les plugins du type que vous écrivez, avec `--list_probes`, `--list_detectors` ou `--list_generators`
## FAQ
Nous avons une FAQ [ici](https://github.com/NVIDIA/garak/blob/main/FAQ.md). N'hésitez pas à nous contacter si vous avez d'autres questions ! [[email protected]](mailto:[email protected])
La documentation de référence du code est disponible sur [garak.readthedocs.io](https://garak.readthedocs.io/en/latest/).
## Citation de garak
Vous pouvez lire le [préprint de l'article sur garak](https://github.com/nvidia/garak/blob/HEAD/garak-paper.pdf). Si vous utilisez garak, veuillez nous citer.```
@article{garak,
title={{garak: A Framework for Security Probing Large Language Models}},
author={Leon Derczynski and Erick Galinkin and Jeffrey Martin and Subho Majumdar and Nanna Inie},
year={2024},
howpublished={\url{https://garak.ai}}
}
"Mentir est une compétence comme une autre, et si vous souhaitez maintenir un certain niveau d'excellence, vous devez vous entraîner constamment" - Elim
Pour les mises à jour et les nouvelles, voir @garak_llm
© 2023- Leon Derczynski ; licence Apache v2, voir LICENSE