{"id":192,"date":"2026-10-08T18:42:58","date_gmt":"2026-10-08T14:42:58","guid":{"rendered":"https:\/\/demensdeum.com\/blog\/2026\/10\/08\/airllm-experiments\/"},"modified":"2026-10-08T19:11:07","modified_gmt":"2026-10-08T15:11:07","slug":"airllm-experiments","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/fr\/2026\/10\/08\/airllm-experiments\/","title":{"rendered":"AirLLM\u00a0: de grands mod\u00e8les de langage sur une carte graphique faible"},"content":{"rendered":"<p>En r\u00e8gle g\u00e9n\u00e9rale, l&#8217;ex\u00e9cution d&#8217;un mod\u00e8le de langage volumineux comportant 70 milliards de param\u00e8tres n\u00e9cessite plusieurs dizaines de gigaoctets de m\u00e9moire vid\u00e9o. AirLLM aborde ce probl\u00e8me plus sereinement et propose une mani\u00e8re diff\u00e9rente : un tel mod\u00e8le peut \u00eatre ex\u00e9cut\u00e9 sur une carte vid\u00e9o avec seulement 4 Go de m\u00e9moire, et sans quantification, distillation et d\u00e9coupage. Dans cette note, je vais essayer de vous expliquer sans h\u00e2te comment fonctionne AirLLM, comment l&#8217;utiliser, et je partagerai mon petit projet AirLLM-experiments, qui rend le travail avec cette biblioth\u00e8que un peu plus pratique.<\/p>\n<h2>Qu&#8217;est-ce qu&#8217;AirLLM<\/h2>\n<p>AirLLM est une biblioth\u00e8que open source pour l&#8217;inf\u00e9rence de grands mod\u00e8les de langage \u00e9crite par Gavin Li. Son id\u00e9e est simple et pourtant \u00e9l\u00e9gante : au lieu de stocker tous les poids du mod\u00e8le en m\u00eame temps dans la m\u00e9moire vid\u00e9o, la biblioth\u00e8que ne charge qu&#8217;une seule couche \u00e0 la fois sur le GPU. Les poids sont stock\u00e9s sur le disque sous forme de fragments d\u00e9coup\u00e9s en couches, et lors de la g\u00e9n\u00e9ration, chaque couche est charg\u00e9e, trait\u00e9e et d\u00e9charg\u00e9e tour \u00e0 tour.<\/p>\n<p>Il s&#8217;ensuit que la quantit\u00e9 de m\u00e9moire vid\u00e9o requise ne d\u00e9pend pas de la taille globale du mod\u00e8le, mais de la taille d&#8217;une de ses couches. C&#8217;est pourquoi le mod\u00e8le 70B tient dans 4 Go, le DeepSeek-V3 sur 671B tient dans environ 12 Go et le Qwen3-235B tient dans environ 3 Go. Mais la taille du mod\u00e8le lui-m\u00eame est limit\u00e9e principalement par l&#8217;espace disque, et non par les capacit\u00e9s de la carte vid\u00e9o.<\/p>\n<p>Ces \u00e9conomies de m\u00e9moire se font au d\u00e9triment de la vitesse\u00a0: chaque couche est lue sur le disque lorsque chaque jeton est g\u00e9n\u00e9r\u00e9, la sortie est donc lente, environ quelques secondes par jeton. AirLLM concerne donc moins une discussion interactive rapide que la possibilit\u00e9 de lancer un mod\u00e8le qui, autrement, ne rentrerait pas dans le mat\u00e9riel.<\/p>\n<h2>Installation<\/h2>\n<p>La biblioth\u00e8que s&#8217;installe depuis PyPI \u00e0 l&#8217;aide de la commande habituelle\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism undefined-numbers lang-unknown\" data-lang=\"unknown\"><code>pip install airllm\n<\/code><\/pre>\n<\/div>\n<p>Lors du premier lancement, le mod\u00e8le sera t\u00e9l\u00e9charg\u00e9 depuis Hugging Face et sera d\u00e9compos\u00e9 en couches. Ce processus est lent et occupe beaucoup d&#8217;espace disque, vous devez donc pr\u00e9parer l&#8217;espace libre \u00e0 l&#8217;avance. Si vous le souhaitez, vous pouvez activer la compression 4 bits ou 8 bits &#8211; la quantification par blocs sera alors appliqu\u00e9e aux poids, ce qui acc\u00e9l\u00e8re le chargement des couches \u00e0 partir du disque d&#8217;environ trois fois, et la pr\u00e9cision est consid\u00e9rablement perdue.<\/p>\n<h2>Exemple de base<\/h2>\n<p>Vous pouvez travailler avec AirLLM presque de la m\u00eame mani\u00e8re qu&#8217;avec un mod\u00e8le classique de transformateurs. Il suffit de saisir une fois l&#8217;ID du mod\u00e8le sur Hugging Face, et tout vous sera alors familier\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism undefined-numbers lang-unknown\" data-lang=\"unknown\"><code>from airllm import AutoModel\n\nMAX_LENGTH = 128\nmodel = AutoModel.from_pretrained(\"Qwen\/Qwen3-32B\")\n\ninput_text = ['What is the capital of United States?']\n\ninput_tokens = model.tokenizer(\n    input_text,\n    return_tensors=\"pt\",\n    return_attention_mask=False,\n    truncation=True,\n    max_length=MAX_LENGTH,\n    padding=False)\n\ngeneration_output = model.generate(\n    input_tokens['input_ids'].cuda(),\n    max_new_tokens=20,\n    use_cache=True,\n    return_dict_in_generate=True)\n\nprint(model.tokenizer.decode(generation_output.sequences[0]))\n<\/code><\/pre>\n<\/div>\n<p>La classe AutoModel elle-m\u00eame d\u00e9termine le type de mod\u00e8le, la m\u00eame ligne peut donc \u00eatre utilis\u00e9e pour Llama, Qwen et DeepSeek. Et si vous prenez un mod\u00e8le comme DeepSeek-V3 avec des param\u00e8tres 671B, il pourra \u00e9galement contenir environ 12 Go de m\u00e9moire vid\u00e9o &#8211; c&#8217;est en grande partie ce qui rend le projet attrayant.<\/p>\n<h2>Lancer sur macOS<\/h2>\n<p>AirLLM fonctionne non seulement sur CUDA, mais \u00e9galement sur Apple Silicon. Sur macOS, il utilise le backend MLX, il faudra donc que mlx et torch soient install\u00e9s et ne prend en charge que les puces Apple. Il existe \u00e9galement une petite limitation : l&#8217;impl\u00e9mentation MLX ne prend en charge que les architectures de type Llama, donc Qwen et les mod\u00e8les similaires ne peuvent pas \u00eatre lanc\u00e9s sur un MacBook de cette mani\u00e8re.<\/p>\n<h2>Utiliser un exemple<\/h2>\n<p>Les exp\u00e9riences AirLLM sont deux petits utilitaires de console interactifs permettant d&#8217;ex\u00e9cuter localement de grands mod\u00e8les de langage. Ils \u00e9liminent le besoin d\u2019\u00e9crire le m\u00eame code \u00e0 chaque fois pour charger le mod\u00e8le et organiser le chat.<\/p>\n<p>Le premier outil, airllm-lib-usage.py, ex\u00e9cute la biblioth\u00e8que AirLLM directement dans le processus Python actuel. Il affiche une liste num\u00e9rot\u00e9e de mod\u00e8les du catalogue g\u00e9n\u00e9ral, si n\u00e9cessaire, il installe les d\u00e9pendances manquantes et ouvre une session de chat. Le runtime MLX est utilis\u00e9 sur macOS, torch est utilis\u00e9 sur d&#8217;autres plates-formes.<\/p>\n<p>Le deuxi\u00e8me outil, airllm-openai-server-client.py, vous aide \u00e0 travailler avec le serveur airllm-openai-server, qui s&#8217;ex\u00e9cute dans Docker et fournit une API compatible OpenAI. Lorsque vous le lancez pour la premi\u00e8re fois, l&#8217;utilitaire demande des param\u00e8tres, collecte l&#8217;image, r\u00e9cup\u00e8re le conteneur et ouvre une discussion en streaming sur le serveur en cours d&#8217;ex\u00e9cution. Lorsqu&#8217;il est lanc\u00e9 \u00e0 plusieurs reprises, il trouve un conteneur existant et le r\u00e9utilise simplement, et stocke le cache du mod\u00e8le dans un volume Docker s\u00e9par\u00e9 afin de ne pas t\u00e9l\u00e9charger \u00e0 nouveau le mod\u00e8le.<\/p>\n<p>La liste des mod\u00e8les disponibles est incluse dans le module commun model_catalog.py, donc les deux outils fonctionnent avec le m\u00eame ensemble. Les commandes de discussion sont \u00e9galement courantes\u00a0: \/help, \/clear, \/exit. Le code source et les instructions sont dans le d\u00e9p\u00f4t\u00a0:<\/p>\n<p><a href=\"https:\/\/github.com\/zefir1990\/AirLLM-experiments\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/zefir1990\/AirLLM-experiments<\/a><\/p>\n<h2>\u00c0 quoi faire attention<\/h2>\n<p>La pr\u00e9paration de la premi\u00e8re r\u00e9ponse peut prendre plusieurs minutes\u00a0: tout d&#8217;abord, AirLLM t\u00e9l\u00e9charge le mod\u00e8le et le d\u00e9coupe en couches, puis commence seulement \u00e0 g\u00e9n\u00e9rer. De plus, la vitesse reste \u00e9galement faible &#8211; il s&#8217;agit d&#8217;un compromis d\u00e9lib\u00e9r\u00e9 dans un souci d&#8217;\u00e9conomie de m\u00e9moire. Pour les mod\u00e8les ferm\u00e9s comme le m\u00e9ta-llama, vous devez accepter les conditions de Hugging Face et transmettre un jeton d&#8217;acc\u00e8s. Il est pr\u00e9f\u00e9rable de ne pas supprimer le cache des mod\u00e8les et fragments t\u00e9l\u00e9charg\u00e9s, sinon tout devra \u00eatre t\u00e9l\u00e9charg\u00e9 \u00e0 nouveau.<\/p>\n<h2>Liens<\/h2>\n<p><a href=\"https:\/\/github.com\/lyogavin\/airllm\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/lyogavin\/airllm<\/a><br \/>\n<a href=\"https:\/\/github.com\/mkamranr\/airllm-openai-server\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/mkamranr\/airllm-openai-server<\/a><br \/>\n<a href=\"https:\/\/github.com\/zefir1990\/AirLLM-experiments\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/zefir1990\/AirLLM-experiments<\/a><br \/>\n<a href=\"https:\/\/pypi.org\/project\/airllm\/\" rel=\"noopener\" target=\"_blank\">https:\/\/pypi.org\/project\/airllm\/<\/a><br \/>\n<a href=\"https:\/\/huggingface.co\/\" rel=\"noopener\" target=\"_blank\">https:\/\/huggingface.co\/<\/a><\/p>\n<h2>Sources<\/h2>\n<p><a href=\"https:\/\/github.com\/lyogavin\/airllm\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/lyogavin\/airllm<\/a><br \/>\n<a href=\"https:\/\/github.com\/zefir1990\/AirLLM-experiments\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/zefir1990\/AirLLM-experiments<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En r\u00e8gle g\u00e9n\u00e9rale, l&#8217;ex\u00e9cution d&#8217;un mod\u00e8le de langage volumineux comportant 70 milliards de param\u00e8tres n\u00e9cessite plusieurs dizaines de gigaoctets de m\u00e9moire vid\u00e9o. AirLLM aborde ce probl\u00e8me plus sereinement et propose une mani\u00e8re diff\u00e9rente : un tel mod\u00e8le peut \u00eatre ex\u00e9cut\u00e9 sur une carte vid\u00e9o avec seulement 4 Go de m\u00e9moire, et sans quantification, distillation et [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-192","post","type-post","status-publish","format-standard","hentry","category-notes"],"translation":{"provider":"WPGlobus","version":"3.0.6","language":"fr","enabled_languages":["en","ru","zh","de","ja","fr","es","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"es":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":true,"content":true,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/comments?post=192"}],"version-history":[{"count":2,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/192\/revisions"}],"predecessor-version":[{"id":194,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/192\/revisions\/194"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/media?parent=192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/categories?post=192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/tags?post=192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}