<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>chatbot &#8211; Smals Research</title>
	<atom:link href="https://www.smalsresearch.be/tag/chatbot/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.smalsresearch.be</link>
	<description></description>
	<lastBuildDate>Thu, 09 Apr 2026 12:23:58 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.smalsresearch.be/wp-content/uploads/2026/01/cropped-cropped-Smals_Research-32x32.png</url>
	<title>chatbot &#8211; Smals Research</title>
	<link>https://www.smalsresearch.be</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>De performance van LLM’s: Een vergelijkende analyse tussen Frans en Nederlands</title>
		<link>https://www.smalsresearch.be/de-performance-van-llms-een-vergelijkende-analyse-tussen-frans-en-nederlands/</link>
		
		<dc:creator><![CDATA[Katy Fokou]]></dc:creator>
		<pubDate>Wed, 04 Mar 2026 15:27:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<guid isPermaLink="false">https://www.smalsresearch.be/?p=26548</guid>

					<description><![CDATA[Uit onze evaluatie van een RAG-chatbot blijkt er een prestatieverschil te bestaan tussen het Frans en het Nederlands, wat wijst op een aanhoudende uitdaging bij het gebruik van meertalige grote taalmodellen (LLM’s). Dit prestatieverschil kan deels worden verklaard door de beschikbaarheid van de middelen die worden gebruikt om deze modellen te trainen, maar er kunnen ook andere factoren meespelen.]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.smalsresearch.be/performance-des-llm-analyse-comparative-entre-le-francais-et-le-neerlandais/" data-type="link" data-id="https://www.smalsresearch.be/performance-des-llm-analyse-comparative-entre-le-francais-et-le-neerlandais/">Version française</a></p>



<p>Het opmerkelijke meertalige potentieel van grote taalmodellen (LLM’s) heeft bijgedragen aan de brede verspreiding en integratie ervan binnen AI-gebaseerde toepassingen. Er bestaan echter prestatieverschillen tussen het Engels en andere talen, met name talen met beperkte middelen.</p>



<p>Bij de evaluatie van een door ons ontwikkelde <a href="https://www.smalsresearch.be/rag-in-practice-webinar-by-smals-research/">RAG-chatbot</a> stelden we een duidelijk verschil vast in de kwaliteit van de antwoorden, afhankelijk van de gebruikte taal. De chatbot leverde namelijk betere antwoorden in het Frans dan in het Nederlands. De in het Frans gegenereerde antwoorden waren vlotter en betrouwbaarder ten opzichte van de door de gebruiker gevraagde informatie. De antwoorden in het Nederlands waren over het algemeen minder relevant. Deze resultaten wijzen op een cruciale uitdaging bij de ontwikkeling van LLM&#8217;s die door chatbots worden gebruikt: hoewel deze indrukwekkende meertalige capaciteiten hebben, vertonen de huidige modellen vaak een uitgesproken voorkeur voor talen met veel middelen, zoals het Engels.</p>



<p>In deze blogpost beschrijven we de resultaten van ons onderzoek naar de door ons vastgestelde taalkloof en tonen we de bevindingen van ons onderzoek.</p>



<h1 class="wp-block-heading">Prestatieverschil tussen het Engels en de andere talen: oorzaken en factoren</h1>



<p>Verschillende factoren dragen bij aan de taalvoorkeur voor het Engels. Deze omvatten:</p>



<ul class="wp-block-list">
<li><strong>Onevenwichtige datasets:</strong> het trainingsproces van grote taalmodellen is gebaseerd op omvangrijke tekstcorpora, maar deze worden sterk gedomineerd door het Engels, gevolgd door talen met veel taalkundige middelen zoals het Chinees, het Frans en het Spaans. Daarentegen zijn de data in talen met beperkte middelen vaak van mindere kwaliteit vanwege het beperkte aantal bronnen. Dit onevenwicht in de data leidt tot slechte prestaties in andere talen dan het Engels, met hogere foutpercentages en hallucinaties tot gevolg. Om dit probleem op te lossen, maken modelontwikkelaars gebruik van een techniek die “interlinguïstische overdracht” genoemd wordt. Hierbij verbetert een model zijn prestaties in minder goed uitgeruste talen door universele of gedeelde taalkundige patronen af te leiden uit talen met veel middelen. Hoewel het exacte percentage Engelstalige data in propriëtaire modellen niet openbaar bekend is, is 93% van de data die worden gebruikt om GPT-3 te trainen in het Engels. Leveranciers van grote taalmodellen, zoals OpenAI en Google, maken vaak gebruik van het Common Crawl-webgegevensarchief, dat zelf wordt gekenmerkt door een dataset waarin het Engels overheerst (44% in het Engels, 4% in het Frans, 2% in het Nederlands). Deze vertekening wordt nog versterkt in gespecialiseerde domeinen zoals financiën en gezondheidszorg, waar hoogwaardige data bijzonder schaars is. Het is belangrijk op te merken dat het Nederlands wordt beschouwd als een taal met hoge middelen in het domein van automatische natuurlijke taalverwerking (NLP), hoewel het over minder middelen beschikt dan het Frans of het Engels.</li>



<li><strong>Morfologie en tokenisatie:</strong> modelarchitecturen zijn vaak geoptimaliseerd voor het Engels. Tokenisatieprocessen kunnen ingewikkeld zijn voor talen die niet met het Latijns alfabet worden geschreven, zoals het Chinees of het Japans, alsook voor talen met een gemiddelde tot hoge morfologische complexiteit, zoals het Nederlands. Engelse tokenizers kunnen het moeilijk hebben met het verwerken van samengestelde woorden (de combinatie van meerdere zelfstandige naamwoorden in een woord), wat kan leiden tot grammaticaal foute resultaten wanneer modellen tekst genereren.</li>
</ul>



<p>Zeer weinig studies hebben de prestaties geanalyseerd van grote taalmodellen in het Frans en het Nederlands. Een onderzoek naar de taalkundige kwaliteit van LLM’s in deze twee talen bracht aan het licht dat de prestaties algemeen beter waren in het Frans dan in het Nederlands, in het bijzonder bij taken waarbij tekst moest worden gegenereerd [1]. Een ander onderzoek rapporteerde betere prestaties van LLM’s in het Engels in vergelijking met het Nederlands bij een vraag-antwoordtaak [2].</p>



<p>In de industrie blijven er grote uitdagingen bestaan met betrekking tot de toepassing van grote taalmodellen op niet-Engelse technische domeinen, met name in de medische en financiële sector. De huidige implementaties vereisen vaak een verfijning van de vooraf getrainde modellen zoals Mistral en Llama om bevredigende prestaties te bereiken.</p>



<p>Een andere bekende uitdaging bij de toepassing van AI-modellen in de Nederlandse taalomgeving is spraakherkenning. Dit is grotendeels een gevolg van de grote variatie in regionale accenten. Onze experimenten met het transcriberen van opnames van Teams-vergaderingen hebben aangetoond dat de Franse transcripties systematisch van betere kwaliteit waren dan de Nederlandse. Gespecialiseerde tools zoals <a href="https://www.sembly.ai/">Sembly</a> leveren echter acceptabele transcriptieresultaten in het Nederlands.</p>



<h1 class="wp-block-heading">Vergelijkende analyse van de prestaties van het Nederlands en het Frans in een chatbot</h1>



<p>Er is een vergelijkende analyse van de prestaties uitgevoerd op een chatbot die is ontwikkeld om vragen van burgers te beantwoorden. Voor de eerste evaluatie van de chatbot hebben we een reeks vragen gebruikt die door experts zijn opgesteld. Deze vragen werden in het Frans en het Nederlands aan de chatbot voorgelegd, waarna de antwoorden door dezelfde expert werden beoordeeld en door twee andere personen werden gecontroleerd. Uit de eerste evaluatie blijkt een aanzienlijk verschil in prestaties tussen de twee talen: de chatbot behaalde een nauwkeurigheid van 95% in het Frans, tegenover 82% in het Nederlands.</p>



<p>Na de implementatie van de chatbot in een productieomgeving werd een tweede evaluatiefase uitgevoerd op basis van vragen die door gebruikers waren ingediend en in een database waren opgeslagen. We merkten opnieuw een verschil in prestaties: 82% nauwkeurigheid in het Frans en 69% in het Nederlands.</p>



<p>Verschillende factoren kunnen bijdragen aan deze waargenomen verschillen, waaronder:</p>



<ul class="wp-block-list">
<li>de vooringenomenheid van de beoordelaars – beoordelaars zijn minder of meer streng in hun beoordelingen;</li>



<li>de variatie in het soort vragen (dubbelzinnig, slecht geformuleerd, niet ter zake) – dezelfde vragen werden niet systematisch in beide talen beoordeeld;</li>



<li>het kwaliteitsverschil bij het ophalen van de bronnen (<em>retrieval</em>) – er zijn verschillen tussen de talen in de data-bronnen die worden opgehaald om de generatie te voeden;</li>



<li>de intrinsieke capaciteiten van het generatieve model (GPT-4o) in beide talen.</li>
</ul>



<p>Er was dus aanvullend onderzoek nodig om de waargenomen verschillen in het Frans en het Nederlands volledig te begrijpen en deze factoren te verminderen.</p>



<h3 class="wp-block-heading"><strong>Test</strong></h3>



<p>Om de prestaties van LLM&#8217;s in zowel het Frans als het Nederlands grondig te evalueren, werd een experiment uitgevoerd met de chatbot. We selecteerden een aantal vragen waarvan de eerdere antwoorden van LLM&#8217;s als onjuist waren beoordeeld, waarbij we ervoor zorgden dat de vragen niet te complex of te simplistisch waren. Het was van cruciaal belang dat elke vraag van een gebruiker tussen het Frans en het Nederlands werd vertaald om een directe vergelijking te vergemakkelijken. Bij het evaluatieproces waren twee onafhankelijke evaluatoren betrokken, een vakexpert en een technisch expert, om vooringenomenheid te beperken en een robuuste evaluatie te garanderen. De evaluatoren beoordeelden de nauwkeurigheid, relevantie en vlotheid van de gegenereerde antwoorden. Daarnaast werden ook andere modellen dan GPT-4o getest.</p>



<p>Naast de tests in het Nederlands en het Frans hebben we ook een test uitgevoerd waarbij vragen in het Nederlands naar het Engels werden vertaald. De antwoorden werden in het Engels gegenereerd en vervolgens opnieuw naar het Nederlands vertaald.</p>



<h3 class="wp-block-heading"><strong>Resultaten</strong></h3>



<p><em>Vraag in het Nederlands, antwoord in het Engels</em></p>



<p>Het experiment waarbij vragen in het Nederlands naar het Engels werden vertaald en hierna de antwoorden naar het Nederlands werden vertaald leverde een genuanceerd resultaat. Hoewel de vertaling van Nederlandstalige vragen naar het Engels leidde tot ietwat betere antwoorden, van 67% naar 73%, verslechterde de kwaliteit van de antwoorden bij het omgekeerde proces, namelijk het vertalen van de gegenereerde Engelse antwoorden naar het Nederlands.</p>



<p><em>Nauwkeurigheid van Franse antwoorden versus nauwkeurigheid van Nederlands antwoorden</em></p>



<p>Tijdens ons experiment hebben we de antwoorden gegenereerd op basis van Nederlandstalige vragen vergeleken met hun Franse equivalenten in verschillende tekstreeksen. We hebben vastgesteld dat de samenstelling van deze reeksen een invloed had op de evaluatie van het model. De scores varieerden namelijk van set tot set voor elk model en elke taal, en de prestatieverschillen tussen de talen kwamen niet altijd tot uiting. Dit onderstreept het belang van het selectieproces van de testvragen: voor onze laatste test hebben we een evenwichtige testset samengesteld met voorbeelden van vragen die door gebruikers in beide talen zijn ingediend en vragen die door domeinexperts zijn opgesteld. In tegenstelling tot wat aanvankelijk werd waargenomen, laten de onderstaande resultaten slechts een klein verschil in nauwkeurigheid zien tussen het Frans en het Nederlands <strong>voor onze use case</strong>.</p>



<p>Tabel 1. Resultaten van de eindevaluatie van de chatbot.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>&nbsp;</td><td><strong>Maximale score</strong><strong></strong></td><td><strong>GPT-5 (OpenAI)</strong><strong></strong></td><td><strong>Gemini (Google)</strong><strong></strong></td><td><strong>o3 (OpenAI)</strong><strong></strong></td><td><strong>Beste score (Gemini)</strong><strong></strong></td></tr><tr><td><strong>FR</strong><strong></strong></td><td>60</td><td>44</td><td><strong>46</strong><strong></strong></td><td>32</td><td><strong>77%</strong><strong></strong></td></tr><tr><td><strong>NL</strong><strong></strong></td><td>60</td><td>38</td><td><strong>43</strong><strong></strong></td><td>32</td><td><strong>72%</strong><strong></strong></td></tr></tbody></table></figure>



<p><em>Opmerking: slecht geformuleerde vragen in het Frans of Nederlands werden uit de testset verwijderd omdat ze moeilijk nauwkeurig in de andere taal te vertalen bleken.</em><em></em></p>



<p><em>Vergelijking van de LLM&#8217;s</em></p>



<p>GPT-5 presteerde goed op het vlak van nauwkeurigheid en beknoptheid. Het vertoonde echter een groter verschil in nauwkeurigheid tussen het Frans en het Nederlands dan de andere modellen. Gemini presteerde weliswaar beter in zowel het Frans als het Nederlands, maar genereerde aanzienlijk langere antwoorden, wat leidde tot een hoger tokengebruik. We hebben ook vastgesteld dat Claude Sonnet, met een vergelijkbare nauwkeurigheid als Gemini, soms Engelse termen invoegde in het gegenereerde antwoord, en dit vaker in het Nederlands dan in het Frans. Na evaluatie concludeerden de experts op dit gebied dat Gemini het meest geschikte model was voor hun use case.</p>



<p><em>Effect van de retrieval</em></p>



<p>Het proces van <a href="https://www.smalsresearch.be/betere-zoekresultaten-met-vector-databases/">retrieval</a> bestaat erin om relevante tekstfragmenten te extraheren om een vraag te beantwoorden vanuit de vector database, afhankelijk van de gelijkenis tussen de vraag en deze fragmenten. Deze gelijkenis wordt berekend met behulp van vectorrepresentaties van de teksten, gegenereerd door een <em>embeddingmodel</em>. We hebben vragen geanalyseerd die aanvankelijk betere resultaten opleverden in het Frans dan in het Nederlands en hebben vastgesteld dat ongeveer 50% van de opgehaalde informatie (context) in beide talen voorkwam. Om de impact van de resterende 50% afwijkende informatie te evalueren, hebben we het model (Gemini) aan identieke contexten onderworpen om zowel Franstalige als Nederlandstalige antwoorden te genereren. Ondanks het gebruik van deze identieke contexten bleef het model prestatieverschillen vertonen tussen het Frans en het Nederlands. Het retrievalproces lijkt dus een beperkte invloed te hebben op het waargenomen prestatieverschil tussen de twee talen.</p>



<h1 class="wp-block-heading">Conclusie en aanbevelingen</h1>



<p>Het prestatieverschil tussen het Nederlands en het Engels in grote taalmodellen is een vaststaand feit, dat geworteld is in de overweldigende dominantie van het Engels in de trainingscorpora. Dit verschil wordt nog versterkt door de specifieke morfologie van het Nederlands. Ter vergelijking: als LLM&#8217;s over het algemeen betere resultaten opleveren in het Frans, is dat te danken aan een betere vertegenwoordiging van de taal in de trainingscorpora.</p>



<p>Ons experiment heeft waardevolle informatie opgeleverd over de prestaties van LLM&#8217;s in een RAG-toepassing (Retrieval Augmented Generation) in het Nederlands en het Frans. Hoewel we aanvankelijk een significant verschil in nauwkeurigheid tussen de antwoorden in het Nederlands en de antwoorden in het Frans constateerden, bleek uit grondig onderzoek dat andere factoren dan de capaciteit van het model de resultaten konden beïnvloeden. Het prestatieverschil is dus minder groot dan we dachten. Bovendien hebben we vastgesteld dat variaties in de samenstelling van de testset kleine schommelingen in de resultaten veroorzaakten. Deze conclusies tonen aan dat de prestaties van LLM&#8217;s zeer gevoelig zijn voor de context en de specifieke formulering van de vragen. We hebben ook een lichte kwaliteitsverbetering&nbsp; van de antwoorden waargenomen bij de Engelse vertaling van Nederlandstalige vragen; dit voordeel werd echter grotendeels tenietgedaan door de daaropvolgende Nederlandse vertaling van deze Engelse antwoorden.</p>



<p>De bovenstaande conclusies gelden voor een chatbot die zorgvuldig opgestelde inhoud in algemene taal gebruikt om vragen te beantwoorden. Ze zijn niet noodzakelijkerwijs van toepassing op andere use cases. Het is daarom essentieel om voor elk geval grondige evaluaties uit te voeren, zeker wanneer men in specifieke domeinen zoals gezondheidszorg, financiën, recht, enzovoort werkt.</p>



<p><strong>Moeten we een eentalig model gebruiken?</strong></p>



<p>We hebben deze vraag niet grondig kunnen onderzoeken. Ons literatuuronderzoek heeft geen overtuigend bewijs opgeleverd dat LLM&#8217;s voor het Nederlands de prestaties verbeteren; integendeel, de aanwezigheid van talen met veel bronnen in meertalige modellen lijkt de prestaties van minder goed bedeelde talen tot op zekere hoogte te verbeteren. Er zijn echter verschillende initiatieven genomen om LLM&#8217;s voor het Nederlands te ontwikkelen. De meest opvallende zijn:</p>



<p>&#8211; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GEITje: model gebaseerd op Mistral 7B en verfijnd voor het Nederlands. Dit model is niet langer beschikbaar vanwege auteursrechtelijke problemen.</p>



<p>&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://gpt-nl.nl/gpt-nl/">GPT-NL</a>: lopend initiatief, ondersteund door Nederland, om een LLM te ontwikkelen die is aangepast aan de Nederlandse taal en cultuur.</p>



<p>Referenties</p>



<ol class="wp-block-list">
<li><a href="https://aclanthology.org/2024.humeval-1.2/">Exploratory Study on the Impact of English Bias of Generative Large Language Models in Dutch and French</a>&nbsp;(Rigouts Terryn &amp; de Lhoneux, HumEval 2024)</li>



<li><a href="https://documentserver.uhasselt.be/bitstream/1942/46335/1/__TRBWS07_FileUploads_2024%20AM%20Presentations_23064_Presentation-137767_23064_TRBAM-25-02712_2025-02-03-05-58-09.pdf">Performance of Large Language Models in Domain-Specific and Underrepresented Languages: A Case Study on the Transportation Domain and Dutch Language</a> (UHasselt)</li>



<li><a href="https://arxiv.org/pdf/2303.12528">MEGA: Multilingual Evaluation of Generative AI</a> (Ahuja et al., 2023)</li>



<li><a href="https://arxiv.org/html/2410.12835v1">A Dutch Financial Large Language Model</a> (Sander Noels, Jorne De Blaere &amp; Tijl De Bie, 2024)</li>



<li><a href="https://blog.premai.io/multilingual-llms-progress-challenges-and-future-directions/">Multilingual LLMs: Progress, Challenges, and Future Directions</a> (PremAI blogpost)</li>



<li><a href="https://hogent-cads.github.io/blog/posts/vlaamse-spraakherkenning/">https://hogent-cads.github.io/blog/posts/vlaamse-spraakherkenning/</a> (HoGent blogpost)</li>



<li><a href="https://www.smalsresearch.be/rag-in-practice-webinar-by-smals-research/">Webinar Smals Research – Generatieve AI: verder dan de hype | Smals Research</a></li>
</ol>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Performance des LLM&#160;: Analyse comparative entre le français et le néerlandais</title>
		<link>https://www.smalsresearch.be/performance-des-llm-analyse-comparative-entre-le-francais-et-le-neerlandais/</link>
		
		<dc:creator><![CDATA[Katy Fokou]]></dc:creator>
		<pubDate>Mon, 09 Feb 2026 16:58:00 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<guid isPermaLink="false">/?p=25886</guid>

					<description><![CDATA[Notre évaluation d'un agent conversationnel RAG a révélé un écart de performance entre le français et le néerlandais, soulignant un défi persistant dans l'utilisation des grands modèles de langage (LLM) multilingues. Cette différence de performance s’explique en partie par la disponibilité des ressources utilisées pour entraîner ces modèles, mais d’autres facteurs peuvent également entrer en jeu.]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.smalsresearch.be/de-performance-van-llms-een-vergelijkende-analyse-tussen-frans-en-nederlands/" data-type="link" data-id="https://www.smalsresearch.be/de-performance-van-llms-een-vergelijkende-analyse-tussen-frans-en-nederlands/">Nederlandse versie</a></p>



<p>Le potentiel multilingue remarquable des grands modèles de langage (LLM) a contribué à leur adoption et à leur intégration généralisées au sein des applications basées par l’IA. Cependant, des disparités de performance existent entre l’anglais et d’autres langues, notamment les langues à faibles ressources.</p>



<p>Lors de l&#8217;évaluation d&#8217;un agent conversationnel (chatbot) RAG que nous avons développé, nous avons constaté une différence nette en termes de qualité des réponses selon la langue utilisée. Plus précisément, le chatbot a produit des réponses de meilleure qualité en français par rapport au néerlandais. Les réponses générées en français se caractérisaient par une plus grande fluidité et une meilleure fidélité aux informations requises par l’utilisateur. Les réponses en néerlandais ont tendance à être moins pertinentes. Ces résultats soulignent un défi crucial dans le développement des LLM utilisés par les chatbots&nbsp;: bien que ceux-ci présentent des capacités multilingues impressionnantes, les modèles actuels manifestent souvent un biais prononcé en faveur des langues à ressources élevées telles que l&#8217;anglais.</p>



<p>Cet article de blogue détaille les résultats de notre recherche sur l&#8217;écart linguistique que nous avons identifié, présentant les résultats de notre investigation.</p>



<h1 class="wp-block-heading">Écart de performance entre l’anglais et les autres langues&nbsp;: causes et facteurs</h1>



<p>Plusieurs facteurs contribuent au biais linguistique en faveur de l’anglais. Ceux-ci incluent&nbsp;:</p>



<ul class="wp-block-list">
<li><strong>Déséquilibre des données</strong>&nbsp;: Le processus d’entraînement des grands modèles de langage repose sur des corpus textuels importants, mais ces derniers sont massivement dominés par l’anglais, suivi par les langues bien dotées en ressources linguistiques telles que le chinois, le français ou l’espagnol. En revanche, les données dans les langues à faibles ressources sont souvent de mauvaise qualité en raison d’un nombre limité de sources. Ce déséquilibre des données entraîne de faibles performances dans les langues autres que l’anglais, donnant des taux d’erreur plus élevés et des hallucinations. Afin de remédier à ce problème, les développeurs de modèles s’appuient sur une technique appelée “transfert inter linguistique”, où un modèle améliore ses performances dans les langues moins dotées en déduisant des schémas linguistiques universels ou partagés à partir des langues à ressources élevées. Bien que le pourcentage exact de données en langue anglaise dans les modèles propriétaires ne soit pas publiquement connu, 93 % des données utilisées pour entraîner GPT-3 sont en anglais. Les fournisseurs de grands modèles de langage, tels qu’OpenAI et Google, utilisent fréquemment l’archive de données web Common Crawl, qui est lui-même caractérisé par un ensemble de données ou l’anglais est prédominant (44 % en anglais, 4 % en français, 2 % en néerlandais). Ce biais est exacerbé dans des domaines spécialisés, tels que la finance et la santé, où les données de haute qualité sont particulièrement rares. Il est important de noter que le néerlandais est considéré comme une langue à ressources élevées dans le domaine du traitement automatique du langage naturel (NLP) bien que disposant de moins de ressources que le français ou l’anglais.</li>



<li><strong>Morphologie et tokenisation</strong>&nbsp;: Les architectures de modèles sont souvent optimisées pour l’anglais. Les processus de tokenisation peuvent être difficiles pour les langues à écriture non latine, telles que le chinois et le japonais, ainsi que pour les langues à morphologie de complexité moyenne à élevée, telles que le néerlandais. Les tokeniseurs centrés sur l’anglais peuvent éprouver des difficultés à traiter les mots composés (la combinaison de plusieurs noms en un seul mot), ce qui peut mener à un résultat grammaticalement incorrect lorsque les modèles génèrent du texte.</li>
</ul>



<p>Très peu d&#8217;études comparatives ont analysé les performances des grands modèles de langage en néerlandais et en français. Une étude analysant la qualité linguistique des LLM dans ces deux langues a révélé que les performances étaient généralement meilleures en français qu&#8217;en néerlandais, en particulier dans les tâches de génération d&#8217;articles [1]. Une autre étude a rapporté de meilleures performances des LLM en anglais comparativement au néerlandais dans une tâche de question-réponse [2].</p>



<p>Des défis importants persistent dans l&#8217;industrie concernant l&#8217;application des grands modèles de langage à des domaines techniques non anglais, en particulier dans des secteurs tels que la médecine et la finance. Les déploiements actuels nécessitent souvent un affinage des modèles pré-entrainés tels que Mistral et Llama pour atteindre des performances satisfaisantes.</p>



<p>Un autre défi bien connu dans l&#8217;application de modèles d&#8217;IA dans l&#8217;environnement linguistique néerlandais est la reconnaissance vocale, largement due à la grande variation des accents régionaux. Nos expériences de transcription d’enregistrements de réunions Teams ont révélé que les transcriptions françaises étaient systématiquement de meilleure qualité que les transcriptions néerlandaises. Cependant, des outils spécialisés tels que Sembly fournissent des résultats de transcription en néerlandais acceptables.<a id="_msocom_1"></a></p>



<h1 class="wp-block-heading">Analyse comparative des performances du néerlandais et du français dans un chatbot</h1>



<p>Une analyse comparative des performances a été menée sur un chatbot développé pour répondre aux questions formulées par les citoyens. Pour l’évaluation initiale du chatbot, nous avons utilisé un ensemble de questions proposées par les experts métier. Ces mêmes questions ont été présentées au chatbot en français et en néerlandais, les réponses ont été évaluées par le même expert et revues par deux autres personnes. Les premières évaluations ont révélé une différence significative de performance entre les deux langues&nbsp;: le chatbot a obtenu un taux de précision de 95 % en français, contre 82 % en néerlandais.</p>



<p>Suite au déploiement du chatbot dans un environnement de production, une seconde phase d’évaluation a été réalisée en utilisant des questions soumises par les utilisateurs et enregistrées dans une base de données. Nous avons de nouveau relevé une divergence de performances&nbsp;: 82 % de précision en français et 69 % en néerlandais.</p>



<p>Plusieurs facteurs pourraient contribuer à ces écarts observés, notamment&nbsp;:</p>



<ul class="wp-block-list">
<li>Les biais introduits par les évaluateurs – les évaluateurs sont plus ou moins sévères dans leurs évaluations;</li>



<li>La variation dans les types de questions (ambiguës, mal formulées, hors sujet) – les mêmes questions n’ont pas été systématiquement évaluées dans les deux langues;</li>



<li>La différence de qualité dans la récupération des sources (<em>retrieval</em>) – on observe des variations entre les langues dans les sources de données récupérées pour alimenter la génération;</li>



<li>Les capacités intrinsèques du modèle génératif (GPT-4o) dans les deux langues.</li>
</ul>



<p>Des investigations supplémentaires étaient donc nécessaires pour pleinement comprendre les différences observées en français et en néerlandais et atténuer ces facteurs.</p>



<h3 class="wp-block-heading"><strong>Test</strong></h3>



<p>Afin d’évaluer rigoureusement les performances des LLM à la fois en français et en néerlandais, une expérience a été menée avec le chatbot. Nous avons sélectionné un échantillon de questions où les réponses précédentes des LLM avaient été jugées inexactes, en nous assurant que les questions étaient ni trop complexes, ni trop simplistes. Il était crucial que chaque question formulée par un utilisateur soit traduite entre le français et le néerlandais pour faciliter une comparaison directe. Le processus d’évaluation a impliqué deux évaluateurs indépendants, un expert métier et un expert technique, afin de réduire les biais et d’assurer une évaluation robuste. Les évaluateurs ont évalué l’exactitude, la pertinence et la fluidité des réponses générées. De plus, d’autres modèles que GPT-4o ont été testés.</p>



<p>En plus des tests en néerlandais et en français, nous avons également réalisé un test où des questions en néerlandais ont été traduites en anglais. Les réponses ont été générées en anglais puis traduites à nouveau en néerlandais.</p>



<h1 class="wp-block-heading"><strong>Résultats</strong></h1>



<p><em>Question en néerlandais, Réponse en anglais</em></p>



<p>L’expérience consistant à traduire des questions posées en néerlandais en anglais et à traduire ensuite des réponses en néerlandais a révélé une performance nuancée. Si la traduction des questions néerlandaises en anglais a entraîné une légère amélioration de la qualité des réponses, passant de 67 % à 73 %, le processus inverse, traduisant les réponses anglaises générées en néerlandais, a davantage dégradé la qualité des réponses.</p>



<p><em>Précision des réponses françaises versus précision des réponses néerlandaises</em></p>



<p>Lors de notre expérience, nous avons comparé les réponses générées à partir de questions en néerlandais et leurs équivalents en français sur plusieurs ensembles de test. Nous avons observé l’influence de la composition de ces ensembles sur l’évaluation du modèle. En effet, Les scores variaient d’un ensemble à l’autre pour chaque modèle et chaque langue, et les disparités de performance entre les langues ne se manifestaient pas toujours. Cela souligne l&#8217;importance du processus de sélection des questions de test: pour notre dernier test, nous avons constitué un ensemble de test équilibré intégrant des échantillons de questions soumises par les utilisateurs dans les deux langues et des questions élaborées par des experts du domaine. Contrairement à ce qui avait été initialement observé, les résultats présentés ci-dessous ne révèlent qu’une différence légère en termes de précision entre le français et le néerlandais <strong>pour notre cas d&#8217;utilisation.</strong></p>



<p>Table 1. Résultats de l’évaluation finale du chatbot.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>
<p>&nbsp;</p>
</td><td><p><strong>Score<span style="font-family: inherit; font-size: inherit; font-weight: inherit; color: initial;"> maximum</span></strong></p></td><td>
<p><strong>GPT-5</strong></p>
</td><td>
<p><strong>Gemini</strong></p>
</td><td>
<p><strong>o3</strong></p>
</td><td><br><p><strong>Meilleur score (Gemini)</strong></p><br></td></tr><tr><td>
<p><strong>FR</strong></p>
</td><td>
<p>60</p>
</td><td>
<p>44</p>
</td><td>
<p><strong>46</strong></p>
</td><td>
<p>32</p>
</td><td>
<p><strong>77%</strong></p>
</td></tr><tr><td>
<p><strong>NL</strong></p>
</td><td>
<p>60</p>
</td><td>
<p>38</p>
</td><td>
<p><strong>43</strong></p>
</td><td>
<p>32</p>
</td><td>
<p><strong>72%</strong></p>
</td></tr></tbody></table></figure>
</div>
</div>



<p><em>Note&nbsp;: Les questions mal formulées en français ou en néerlandais ont été exclues de l&#8217;ensemble de test car elles se sont révélées difficiles à traduire avec précision dans l&#8217;autre langue.</em></p>



<p><em>Comparaison des LLM</em></p>



<p>GPT-5 a démontré de bonnes performances en termes de précision et de concision, cependant il a présenté un écart de précision plus important entre le français et les néerlandais que les autres modèles. Gemini, bien qu’il affiche de meilleures performances tant en français qu’en néerlandais, a généré des réponses notablement plus longues, ce qui a entraîné une utilisation de jetons plus élevée. Nous avons également observé que Claude Sonnet, qui présente une précision similaire à celle de Gemini, avait quelques fois intégré de l’anglais dans la réponse générée, plus souvent en néerlandais qu’en français. Après évaluation, les experts du domaine ont conclu que Gemini était le modèle le plus adapté à leur cas d’utilisation.</p>



<p><em>Effet de la récupération</em></p>



<p>Le processus de <a href="https://www.smalsresearch.be/de-meilleurs-resultats-de-recherche-grace-aux-bases-de-donnees-vectorielles/" data-type="link" data-id="https://www.smalsresearch.be/de-meilleurs-resultats-de-recherche-grace-aux-bases-de-donnees-vectorielles/">récupération </a>consiste à extraire des fragments de texte pertinents pour répondre à une question à partir de la base de données vectorielle, en fonction de la similarité entre la question et ces fragments. Cette similarité est calculéee à l&#8217;aide des représentations vectorielles des textes, générées par un modèle d&#8217;<em>embedding</em>. Nous avons analysé des questions qui avaient donné initialement de meilleurs résultats en français qu’en néerlandais et avons observé qu’environ 50 % de l’information récupérée (contexte) était partagée entre les deux langues. Afin d’évaluer l’impact des 50 % restants d’informations divergentes, nous avons soumis le modèle (Gemini) à des contextes identiques pour générer des réponses tant en français qu’en néerlandais. Malgré l’utilisation de ces contextes identiques, le modèle a continué à présenter des disparités de performance entre le français et le néerlandais. Par conséquent, le processus de récupération semble avoir une influence limitée sur l’écart de performance observé entre les deux langues.</p>



<h1 class="wp-block-heading">Conclusions et recommandations</h1>



<p>L’écart de performance des grands modèles de langage rapporté entre le néerlandais et &nbsp;l’anglais est un fait établi, enraciné dans la domination écrasante de l’anglais dans les corpus d’entraînement. Cet écart est exacerbé par la morphologie spécifique du néerlandais. Comparativement, si les LLM produisent généralement de meilleurs résultats en français, cela est dû à une meilleure représentation de la langue au sein des corpus d’entraînement.</p>



<p>Notre expérience a fourni des informations précieuses sur les performances des LLM dans une application RAG (Retrieval Augmented Generation) en néerlandais et en français. Bien que nous ayons initialement observé une différence significative en termes de justesse entre les réponses en néerlandais et les réponses en français, des investigations approfondies ont révélé que d’autres facteurs que la capacité du modèle pouvaient influencer les résultats. L’écart de performance est donc moins important que ce que nous pensions. De plus, nous avons constaté que les variations dans la composition de l’ensemble de test introduisaient de légères fluctuations dans les résultats. Ces conclusions démontrent que la performance des LLM est très sensible au contexte et à la formulation spécifique des questions. Nous avons également observé une légère amélioration de la qualité des réponses lors de la traduction des questions néerlandaises en anglais; cependant, cet avantage a été largement annulé par la traduction ultérieure de ces réponses anglaises en néerlandais.</p>



<p>Les conclusions présentées ci-dessus sont valables lorsqu’on considère un chatbot utilisant des contenus soigneusement rédigées dans un langage commun pour répondre à des questions. Elles ne sont pas nécessairement applicables à d’autres cas d’utilisation, il est donc essentiel de réaliser des évaluations approfondies pour chaque cas, en particulier lorsqu’on travaille dans des domaines spécifiques tels que la santé, la finance, le droit…</p>



<h3 class="wp-block-heading"><strong>Devrions-nous utiliser un modèle monolingue&nbsp;?</strong></h3>



<p>Nous n’avons pas été en mesure d’examiner cette question de manière approfondie. Notre recherche dans la littérature n’a pas révélé de preuves solides indiquant une amélioration des performances grâce aux LLM dédiés au néerlandais&nbsp;; a contrario, la présence de langues à ressources élevées dans les modèles multilingues semble améliorer la performance de langues moins dotées jusqu’à un certain degré. Cependant, plusieurs initiatives ont été lancées pour le développement de LLM en néerlandais. Les plus notables sont&nbsp;:</p>



<ul class="wp-block-list">
<li>GEITje&nbsp;: Un modèle basé sur Mistral 7B et affiné sur le néerlandais. Ce modèle n’est plus disponible en raison de problèmes de droits d’auteur.</li>



<li><a href="https://gpt-nl.nl/gpt-nl/">GPT-NL</a>&nbsp;: Une initiative en cours, soutenue par les Pays-Bas, visant à développer un LLM adapté à la langue et à la culture néerlandaise.</li>
</ul>



<p><strong>Références</strong></p>



<ol class="wp-block-list">
<li><a href="https://aclanthology.org/2024.humeval-1.2/">Exploratory Study on the Impact of English Bias of Generative Large Language Models in Dutch and French</a>(Rigouts Terryn &amp; de Lhoneux, HumEval 2024)</li>



<li><a href="https://documentserver.uhasselt.be/bitstream/1942/46335/1/__TRBWS07_FileUploads_2024%20AM%20Presentations_23064_Presentation-137767_23064_TRBAM-25-02712_2025-02-03-05-58-09.pdf">Performance of Large Language Models in Domain-Specific and Underrepresented Languages: A Case Study on the Transportation Domain and Dutch Language</a> (UHasselt)</li>



<li><a href="https://arxiv.org/pdf/2303.12528">MEGA: Multilingual Evaluation of Generative AI</a> (Ahuja et al., 2023)</li>



<li><a href="https://arxiv.org/html/2410.12835v1">A Dutch Financial Large Language Model</a> (Sander Noels, Jorne De Blaere &amp; Tijl De Bie, 2024)</li>



<li><a href="https://blog.premai.io/multilingual-llms-progress-challenges-and-future-directions/">Multilingual LLMs: Progress, Challenges, and Future Directions</a> (article de blogue PremAI)</li>



<li><a href="https://hogent-cads.github.io/blog/posts/vlaamse-spraakherkenning/">https://hogent-cads.github.io/blog/posts/vlaamse-spraakherkenning/</a> (article de blogue HoGent)</li>
</ol>



<p>&nbsp;</p>


]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zin, Onzin, en Nut van LLMs: Zijn ze de Hype waard?</title>
		<link>https://www.smalsresearch.be/zin-onzin-en-nut-van-llms-zijn-ze-de-hype-waard/</link>
					<comments>https://www.smalsresearch.be/zin-onzin-en-nut-van-llms-zijn-ze-de-hype-waard/#comments</comments>
		
		<dc:creator><![CDATA[Koen Vanderkimpen]]></dc:creator>
		<pubDate>Wed, 10 Dec 2025 09:22:56 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[software engineering]]></category>
		<guid isPermaLink="false">/?p=24386</guid>

					<description><![CDATA[We hebben waarschijnlijk het moment bereikt waarop de hype over AI op zijn grootst is: men is langs één kant laaiend enthousiast over AI, maar hier en daar raken mensen al gedesillusioneerd. Ook spreekt men meer en meer over een bubbel in de markt van de grote tech-spelers. Maar hoe nuttig zijn LLMs momenteel nu [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image alignleft size-full is-resized"><a href="/wp-content/uploads/2025/11/yin-yang-llm.png"><img fetchpriority="high" decoding="async" width="520" height="514" src="/wp-content/uploads/2025/11/yin-yang-llm.png" alt="" class="wp-image-24491" style="width:120px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/yin-yang-llm.png 520w, https://www.smalsresearch.be/wp-content/uploads/2025/11/yin-yang-llm-300x297.png 300w" sizes="(max-width: 520px) 100vw, 520px" /></a></figure>



<p class="justify-text">We hebben waarschijnlijk het moment bereikt waarop de hype over AI op zijn grootst is: men is langs één kant laaiend enthousiast over AI, maar hier en daar raken mensen al gedesillusioneerd. Ook spreekt men meer en meer over een bubbel in de markt van de grote tech-spelers. Maar hoe nuttig zijn LLMs momenteel nu echt? Kunnen we nog veel verbetering verwachten? En hoe zit dat met die hallucinaties?</p>



<span id="more-24386"></span>



<p class="justify-text">Waarschijnlijk heb je het zelf al meegemaakt: je praat met ChatGPT of een andere slimme chatbot, en deze vertelt je vol vertrouwen iets waarvan je weet dat het niet klopt. Of je bent een developer, en die <a href="https://blog.singleton.io/posts/2025-06-14-coding-agents-cross-a-chasm/">coding assistant werkt best wel goed</a>, tot je <a href="https://martinfowler.com/articles/pushing-ai-autonomy.html">naar wat meer verlangt</a>, maar die nieuw toegevoegde feature aan je programma <a href="https://www.csoonline.com/article/4053635/when-ai-nukes-your-database-the-dark-side-of-vibe-coding.html">hopeloos tekort schiet</a>. En dat zijn nog maar je eigen, bescheiden, ervaringen: wat je hoort van anderen, of op het nieuws of via sociale media, is allicht nog veel extremer: vreugdekreten over hoe we, dankzij AI, een volgende industriële revolutie tegemoet gaan en doemberichten dat mensen hun job erdoor zullen verliezen, versus artikels die vertellen over hoe AI projecten maar blijven mislukken en verhalen over wat voor <a href="https://www.vrt.be/vrtnws/nl/2023/03/24/chatgpt-nepbronnen/">belachelijke of zelfs gevaarlijke hallucinaties</a> uit de AI chatbots blijven komen. Dus wat moet je er nu van denken?</p>



<figure class="wp-block-image alignright size-full is-resized is-style-rounded"><a href="/wp-content/uploads/2025/11/stochastic-parrot.jpeg"><img decoding="async" width="1024" height="1024" src="/wp-content/uploads/2025/11/stochastic-parrot.jpeg" alt="" class="wp-image-24485" style="width:392px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot.jpeg 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-150x150.jpeg 150w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-300x300.jpeg 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-768x768.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p class="justify-text">Om dit enigszins beter te begrijpen: een heel kort, niet te technisch, intermezzo over wat LLMs alweer zijn (mijn excuses dat ik daarbij opzettelijk vaag blijf: voor een betere uitleg raad ik de <a href="/chatgpt-een-eerste-indruk/" data-type="post" data-id="17969">blogposts</a> van mijn <a href="/1-jaar-chatgpt/" data-type="post" data-id="19172">collega&#8217;s</a> aan): AI taalmodellen doen voorspellingen over wat het volgende stukje tekst moet zijn, aan de hand van probabiliteiten. Ze zijn getraind op zó veel tekst, dat de <em>in se</em> willekeurige zinnen die eruit rollen, daardoor van een hoge kwaliteit zijn en perfect juist <em>klinken </em>(en het vaak genoeg ook <em>zijn</em>). Echt nadenken zoals een mens doen ze dus niet; het is heel erg &#8220;text based&#8221;. Het is meer het vinden en herhalen van patronen, dan écht begrip; de intelligentie erin ontstaat als <a href="https://nl.wikipedia.org/wiki/Emergentie">emergent verschijnsel</a>. De leukste naam die ik er al voor gehoord heb is &#8220;<a href="https://en.wikipedia.org/wiki/Stochastic_parrot">probabilistische papegaai</a>&#8220;.</p>



<p class="justify-text">Volgens Gartner zitten we nu al <a href="https://www.gartner.com/en/articles/hype-cycle-for-artificial-intelligence">voorbij de piek van opgeblazen verwachtingen en in de trog van desillusie</a>. Ook <a href="https://ai.plainenglish.io/wall-street-is-wrong-about-artificial-intelligence-4d58369ddcb2">andere verslaggevers</a> spreken van een hype of bubbel. Er worden ettelijke miljarden geïnvesteerd in nieuwe datacenters om de AI-machine te voeden, soms zelfs met inbegrip van nieuwe energiecentrales, terwijl de <a href="https://www.computerworld.com/article/3998244/ai-chatbots-see-fast-adoption-but-deliver-minimal-productivity-gains-study-finds.html">winstgevendheid voorlopig nog ver te zoeken</a> is. Is het effectief een bubbel? Dat hangt af van je <a href="https://danielmiessler.com/blog/no-ai-is-not-a-bubble">definitie van bubbel</a>&#8230; Het lijkt in elk geval een grote, soms geostrategische gok, op de volgende technologie die de wereld drastisch kan veranderen en verbeteren, of zelfs veroveren; misschien zelfs vernietigen&#8230; En op moment van schrijven deinzen sommigen er niet van terug om te zeggen dat de luchtbel weldra zal barsten, met als belangrijkste argumenten de <a href="https://graceblakeley.substack.com/p/the-ai-circular-economy">circulaire investeringen</a> van een aantal grote bedrijven in elkaars capaciteit, en het <a href="https://www.bbc.com/news/articles/cpd2qv58yl5o">openstellen van ChatGPT voor erotische inhoud</a>, een zet die meer op cashflow-druk dan op ruimdenkendheid lijkt te duiden.</p>



<p class="justify-text">Bijkomend probleem is dat momenteel ook de <a href="https://olivermolander.medium.com/gartners-ai-hype-cycle-way-passed-its-due-date-and-are-we-entering-a-classical-ml-winter-7c09041c72c4">investeringen in LLM de wind wegnemen uit de zeilen van een aantal andere zeer nuttige AI-technologieën</a> (maar wanneer de storm is gaan liggen kunnen de datacenters misschien wel van pas komen voor deze laatste). Stemmen gaan trouwens op dat we voor échte intelligentie <a href="https://www.forbes.com/sites/robtoews/2023/09/03/transformers-revolutionized-ai-what-will-replace-them/">nóg een andere AI technologie</a> zullen moeten ontwikkelen (al zal het uiteindelijk wel iets zijn dat <a href="https://www.a16z.news/p/bitter-economics">gebruik maakt van alle rekenkracht die we nu uitrollen</a>), en dat <a href="https://thenewstack.io/entering-ai-autumn-why-llms-are-nearing-their-limit/">LLMs stilaan op hun limieten</a> botsen, met steeds kleiner wordende incrementele verbeteringen (en <a href="https://tweakers.net/nieuws/241122/wetenschappers-vinden-fouten-in-445-veiligheidstests-voor-ai-modellen.html">opgeklopte testresultaten</a>). Ondanks <a href="https://www.incompleteideas.net/IncIdeas/BitterLesson.html">de bittere les dat meer data en rekenkracht de grootste vooruitgang</a> mogelijk hebben gemaakt, gaan er nu stemmen op dat men <a href="https://www.businessinsider.com/openai-cofounder-ilya-sutskever-scaling-ai-age-of-research-dwarkesh-2025-11">met LLMs geen Artificial General Intelligence (AGI) zal kunnen bouwen</a>; men zal nieuwe research moeten aanboren. En ondertussen kan men ook aantonen dat de <a href="https://tweakers.net/nieuws/239420/openai-rapport-hallucinaties-zijn-wiskundig-inherent-aan-huidige-ai-aanpak.html">hallucinaties er gewoon bij horen</a> en <a href="https://openai.com/nl-NL/index/why-language-models-hallucinate/">allicht nooit volledig weg te krijgen zullen zijn</a>: onkruid vergaat niet. </p>



<figure class="wp-block-image alignleft size-full is-resized"><a href="/wp-content/uploads/2025/11/llm-garden.jpeg"><img decoding="async" width="1024" height="1024" src="/wp-content/uploads/2025/11/llm-garden.jpeg" alt="" class="wp-image-24489" style="width:424px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden.jpeg 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-150x150.jpeg 150w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-300x300.jpeg 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-768x768.jpeg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p class="justify-text">Maar in een tuin waar onkruid groeit, kan men toch ook goede dingen laten groeien, met wat moeite. En in zo&#8217;n tuin hebben LLMs wel degelijk hun nut: daar waar een taak vooral gaat over tekst en taal, zijn ze bijvoorbeeld heel krachtig (denk aan samenvatten, vertalen, zaken verzinnen, zeer eenvoudige redeneringen opbouwen, &#8230;). En ook voor programmeren (wat een soort omgaan met een specifiek soort taal is), merken we enthousiasme van vele developers die hun productiviteit zagen stijgen (maar <a href="/ai-om-de-veiligheid-van-de-code-te-verbeteren-deel-1-veiligheid-van-de-gegenereerde-code/">security blijft een aandachtspunt!</a>). Als algemene slimme assistent kan het ook een rol spelen, zolang de gebruiker zelf voldoende onderlegd is in een onderwerp en kritisch is ingesteld. En misschien moeten ze gewoon nog verder <a href="https://jenson.org/boring/">evolueren tot de beste tool voor een bepaalde niche</a> van taken.</p>



<p class="justify-text">Ook zelf heb ik een genuanceerd verhaal te vertellen: in mijn <a href="/vibe-coding-met-agentic-ides/" data-type="post" data-id="22499">vorige blogpost</a> had ik het over een aantal kleine successen met <a href="https://www.infoworld.com/article/4058076/vibe-coding-and-the-future-of-software-development.html">vibe coding</a>, en de beperkingen van het AI, wanneer de taken groter of complexer worden. Hetzelfde zie ik in het werk dat ik sindsdien heb verricht: het analyseren en vertalen van legacy code met behulp van deze taalmodellen. Ook daar dus een gemengd succes: geen toverstokjes, nauwelijks of moeilijk te automatiseren, maar toch een zichtbare tijdswinst bij het begrijpen van middelmatig grote en het herschrijven van kleine stukken code van dit soort projecten (meer details daarover in een komende blogpost).</p>



<h2 class="wp-block-heading">Conclusie</h2>



<p class="justify-text">Een LLM is slechts één van de vele intelligente technologieën die we momenteel aan onze vingertippen hebben, al zij het wel de meest toegankelijke en zichtbare. Misschien vandaar zowel de hype als de controverse?</p>



<p class="justify-text">Zijn LLMs nuttig? Ik zou durven argumenteren van wel. Met de huidige stand van de technologie is het echter van groot belang dit te nuanceren: zet een LLM als <a href="https://leadershiplighthouse.substack.com/p/i-went-all-in-on-ai-the-mit-study">powertool ter beschikking</a> van een menselijke expert! <strong>De echte waarde ligt dus niet in vervanging, maar in augmentatie</strong>. Laten we het komende jaar kijken of alle <a href="/ai-agents-voordelen-uitdagingen-en-usecases/" data-type="post" data-id="22407">agent-based systemen</a> hier verandering in brengen&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.smalsresearch.be/zin-onzin-en-nut-van-llms-zijn-ze-de-hype-waard/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Sens, absurdité et utilité des LLM : méritent-ils ce battage médiatique ?</title>
		<link>https://www.smalsresearch.be/sens-absurdite-et-utilite-des-llm-meritent-ils-ce-battage-mediatique/</link>
		
		<dc:creator><![CDATA[Koen Vanderkimpen]]></dc:creator>
		<pubDate>Wed, 10 Dec 2025 09:17:25 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[software engineering]]></category>
		<guid isPermaLink="false">/?p=24579</guid>

					<description><![CDATA[Nous avons probablement atteint le point culminant du battage médiatique autour de l&#8217;IA&#160;: d&#8217;un côté, l&#8217;IA suscite l&#8217;enthousiasme, de l&#8217;autre, elle commence déjà à créer la désillusion. On parle aussi de plus en plus d&#8217;une bulle sur le marché des grands acteurs technologiques. Mais quelle est réellement l&#8217;utilité des LLM à l&#8217;heure actuelle&#160;? Pouvons-nous encore [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image alignleft size-full is-resized"><a href="/wp-content/uploads/2025/11/yin-yang-llm.png"><img loading="lazy" decoding="async" width="520" height="514" src="/wp-content/uploads/2025/11/yin-yang-llm.png" alt="" class="wp-image-24491" style="width:143px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/yin-yang-llm.png 520w, https://www.smalsresearch.be/wp-content/uploads/2025/11/yin-yang-llm-300x297.png 300w" sizes="auto, (max-width: 520px) 100vw, 520px" /></a></figure>



<p class="justify-text">Nous avons probablement atteint le point culminant du battage médiatique autour de l&#8217;IA&nbsp;: d&#8217;un côté, l&#8217;IA suscite l&#8217;enthousiasme, de l&#8217;autre, elle commence déjà à créer la désillusion. On parle aussi de plus en plus d&#8217;une bulle sur le marché des grands acteurs technologiques. Mais quelle est réellement l&#8217;utilité des LLM à l&#8217;heure actuelle&nbsp;? Pouvons-nous encore espérer de nombreuses améliorations&nbsp;? Et qu&#8217;en est-il des hallucinations&nbsp;?</p>



<span id="more-24579"></span>



<p class="justify-text">Vous avez probablement déjà vécu cette situation&nbsp;: vous discutez avec ChatGPT ou un autre robot conversationnel «&nbsp;intelligent&nbsp;» et celui-ci produit sans détour une affirmation que vous savez fausse. Ou vous êtes développeur et votre <a href="https://blog.singleton.io/posts/2025-06-14-coding-agents-cross-a-chasm/">assistant de codage fonctionne plutôt bien</a>, jusqu&#8217;à <a href="https://martinfowler.com/articles/pushing-ai-autonomy.html">ce que vous en demandiez plus</a>, mais la nouvelle fonctionnalité ajoutée à votre programme <a href="https://www.csoonline.com/article/4053635/when-ai-nukes-your-database-the-dark-side-of-vibe-coding.html">est loin d&#8217;être à la hauteur</a>. Et ce ne sont là que vos propres expériences, modestes. En effet, les expériences relatées par les autres ou celles relayées dans la presse ou sur les réseaux sociaux sont sans doute bien plus extrêmes&nbsp;: d&#8217;un côté, des cris de joie à l&#8217;idée que l&#8217;IA amorce une nouvelle révolution industrielle et des messages alarmistes selon lesquels elle entraînera des pertes d&#8217;emploi, de l&#8217;autre, des articles qui disent que les projets d&#8217;IA ne cessent d&#8217;échouer et des récits sur <a href="https://www.vrt.be/vrtnws/nl/2023/03/24/chatgpt-nepbronnen/">les hallucinations ridicules, voire dangereuses</a> que ne cessent de produire les robots conversationnels basés sur l’IA. Que faut-il dès lors en penser&nbsp;?</p>



<figure class="wp-block-image alignright size-full is-resized is-style-rounded"><a href="/wp-content/uploads/2025/11/stochastic-parrot.jpeg"><img loading="lazy" decoding="async" width="1024" height="1024" src="/wp-content/uploads/2025/11/stochastic-parrot.jpeg" alt="" class="wp-image-24485" style="width:414px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot.jpeg 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-150x150.jpeg 150w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-300x300.jpeg 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/stochastic-parrot-768x768.jpeg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<p class="justify-text">Pour une meilleure compréhension, un bref intermède, pas trop technique, sur ce que sont les LLM (je vous prie de m&#8217;excuser de rester volontairement vague à ce sujet&nbsp;: pour une meilleure explication, je vous recommande les <a href="/chatgpt-een-eerste-indruk/">articles de blog</a> de mes <a href="/1-an-chatgpt/" data-type="post" data-id="19587">collègues</a>)&nbsp;: les modèles de langage d&#8217;IA prédisent ce que doit être le prochain morceau de texte, en se basant sur des probabilités. Ils ont été entraînés sur une telle quantité de texte que les phrases aléatoires qu&#8217;ils produisent sont de grande qualité et semblent parfaitement cohérentes (et le sont souvent). Ils ne réfléchissent donc pas comme un être humain&nbsp;: leur fonctionnement est très &#8220;basé sur le texte&#8221;. Il s&#8217;agit davantage de trouver et de répéter des modèles que de faire preuve d&#8217;une véritable compréhension&nbsp;; l&#8217;intelligence qui s&#8217;en dégage est un <a href="https://fr.wikipedia.org/wiki/%C3%89mergence">phénomène émergent</a>. Le nom le plus cocasse que j&#8217;ai entendu jusqu&#8217;à présent est &#8220;<a href="https://fr.wikipedia.org/wiki/Perroquet_stochastique">perroquet stochastique</a>&#8220;.</p>



<p class="justify-text">Selon Gartner, nous avons déjà <a href="https://www.gartner.com/en/articles/hype-cycle-for-artificial-intelligence">dépassé le pic des attentes déraisonnables et nous sommes désormais dans la phase de désillusion</a>. <a href="https://ai.plainenglish.io/wall-street-is-wrong-about-artificial-intelligence-4d58369ddcb2">D&#8217;autres journalistes</a> parlent d&#8217;un effet de mode ou d&#8217;une bulle.<br>Des milliards sont investis dans de nouveaux centres de données pour alimenter la machine IA, parfois même avec de nouvelles centrales électriques, alors que <a href="https://www.computerworld.com/article/3998244/ai-chatbots-see-fast-adoption-but-deliver-minimal-productivity-gains-study-finds.html">la rentabilité est encore loin d&#8217;être atteinte</a>. S&#8217;agit-il réellement d&#8217;une bulle&nbsp;? Tout dépend de votre <a href="https://danielmiessler.com/blog/no-ai-is-not-a-bubble">définition d&#8217;une bulle</a>&#8230; En tout cas, cela ressemble à un pari énorme, parfois géostratégique, sur la prochaine technologie qui pourrait changer et <a>améliorer</a> radicalement le monde, voire le conquérir, voire le détruire&#8230; Tandis que j&#8217;écris ces lignes, certains n&#8217;hésitent pas à affirmer que la bulle est sur le point d&#8217;éclater, avec comme principaux arguments les <a href="https://graceblakeley.substack.com/p/the-ai-circular-economy">investissements circulaires</a> d&#8217;un certain nombre de grandes entreprises dans leurs capacités respectives et <a href="https://www.bbc.com/news/articles/cpd2qv58yl5o">l&#8217;ouverture de ChatGPT au contenu érotique</a>, une décision qui semble davantage refléter une pression sur les flux de trésorerie qu&#8217;une ouverture d&#8217;esprit.</p>



<p class="justify-text">Un autre problème réside dans le fait qu&#8217;actuellement, <a href="https://olivermolander.medium.com/gartners-ai-hype-cycle-way-passed-its-due-date-and-are-we-entering-a-classical-ml-winter-7c09041c72c4">les investissements dans les LLM freinent également le développement d&#8217;un certain nombre d&#8217;autres technologies d&#8217;IA très utiles</a> (mais lorsque la tempête se sera calmée, les centres de données pourraient bien s&#8217;avérer utiles pour ces dernières). Certains pensent d&#8217;ailleurs que pour obtenir une véritable intelligence, nous devrons développer <a href="https://www.forbes.com/sites/robtoews/2023/09/03/transformers-revolutionized-ai-what-will-replace-them/">une autre technologie d&#8217;IA</a> (même si, au final, celle-ci <a href="https://www.a16z.news/p/bitter-economics">utilisera toute la puissance de calcul que nous déployons actuellement </a>), et que <a href="https://thenewstack.io/entering-ai-autumn-why-llms-are-nearing-their-limit/">les LLM atteignent peu à peu leurs limites</a>, avec des améliorations incrémentielles de plus en plus faibles (et <a href="https://www.begeek.fr/les-benchmarks-dia-sous-le-feu-des-critiques-424095">des résultats de tests gonflés</a>). Malgré <a href="https://algonaute.fr/fr/stupefiant.html">la leçon amère</a> que davantage de données et de puissance de calcul ont permis les plus grands progrès, des voix s&#8217;élèvent maintenant pour dire qu&#8217;on ne pourra pas construire une Intelligence Artificielle Générale (AGI) avec les LLM ; il faudra se tourner vers de nouvelles recherches. Et entre-temps, on peut aussi démontrer que <a href="https://intelligence-artificielle.developpez.com/actu/375803/OpenAI-l-avoue-generation-de-contre-verites-de-citations-fictives-ou-de-faits-inexacts-les-hallucinations-de-ChatGPT-ne-disparaitront-jamais-L-IA-generative-face-a-sa-limite-structurelle/">les hallucinations en font tout simplement partie</a> et <a href="https://openai.com/fr-FR/index/why-language-models-hallucinate/">qu&#8217;elles ne disparaîtront probablement jamais complètement</a>&nbsp;: les mauvaises herbes ne disparaissent jamais. </p>



<figure class="wp-block-image alignleft size-full is-resized"><a href="/wp-content/uploads/2025/11/llm-garden.jpeg"><img loading="lazy" decoding="async" width="1024" height="1024" src="/wp-content/uploads/2025/11/llm-garden.jpeg" alt="" class="wp-image-24489" style="width:424px;height:auto" srcset="https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden.jpeg 1024w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-150x150.jpeg 150w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-300x300.jpeg 300w, https://www.smalsresearch.be/wp-content/uploads/2025/11/llm-garden-768x768.jpeg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<p class="justify-text">Mais dans un jardin envahi par les mauvaises herbes, de belles plantations sont tout de même possibles, moyennant quelques efforts. Et dans un tel jardin, les LLM ont bel et bien leur utilité&nbsp;: lorsqu&#8217;une tâche concerne principalement le texte et le langage, ils sont par exemple très performants (pensez au résumé, à la traduction, à la création, à la construction de raisonnements très simples&#8230;). Et même pour la programmation (qui est une sorte de manipulation d&#8217;un langage spécifique), nous constatons l&#8217;enthousiasme de nombreux développeurs qui ont vu leur productivité augmenter (mais <a href="/ia-pour-ameliorer-securite-du-code-1/">la sécurité demeure un point d&#8217;attention&nbsp;!</a>). En tant qu&#8217;assistant intelligent général, les LLM peuvent également jouer un rôle, à condition que l&#8217;utilisateur soit suffisamment informé sur un sujet et ait l&#8217;esprit critique. Et peut-être doivent-ils simplement continuer à <a href="https://jenson.org/boring/">évoluer pour devenir le meilleur outil pour une certaine niche</a> de tâches.</p>



<p class="justify-text">J&#8217;ai moi-même une histoire nuancée à raconter&nbsp;: dans mon <a href="/vibe-coding-avec-les-ides-agentique/">précédent article de blog</a>, j&#8217;ai évoqué quelques petits succès avec le <a href="https://www.infoworld.com/article/4058076/vibe-coding-and-the-future-of-software-development.html">vibe coding</a>, ainsi que les limites de l&#8217;IA lorsque les tâches deviennent plus importantes ou plus complexes. Je constate la même chose dans le travail que j&#8217;ai effectué depuis&nbsp;: l&#8217;analyse et la traduction de code hérité à l&#8217;aide de ces modèles de langage. Là aussi, le succès est mitigé&nbsp;: pas de baguette magique, difficile voire impossible à automatiser, mais tout de même un gain de temps visible dans la compréhension des codes de taille moyenne et la réécriture des petits morceaux de code de ce type de projets (plus de détails à ce sujet dans un prochain article de blog).</p>



<p><strong>Conclusion</strong></p>



<p class="justify-text">Un LLM n&#8217;est qu&#8217;une des nombreuses technologies «&nbsp;intelligentes&nbsp;» disponibles actuellement, même s&#8217;il s&#8217;agit de la plus accessible et la plus visible. C&#8217;est peut-être ce qui explique à la fois l&#8217;engouement et la controverse qu&#8217;elle suscite.</p>



<p class="justify-text">Les LLM sont-ils utiles&nbsp;? J&#8217;oserais dire que oui. Cependant, compte tenu de l&#8217;état actuel de la technologie, il est fondamental de nuancer cette affirmation&nbsp;: mettez un LLM à la disposition d&#8217;un expert humain en tant qu&#8217;<a href="https://leadershiplighthouse.substack.com/p/i-went-all-in-on-ai-the-mit-study">outil puissant</a>&nbsp;! <strong>La véritable valeur ne réside donc pas dans le remplacement, mais dans l&#8217;augmentation.</strong> Nous verrons si tous les <a href="/agents-ia-avantages-defis-et-cas-utilisation/">systèmes basés sur des agents</a> changeront la donne au cours de l&#8217;année à venir.<a id="_msocom_1"></a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PII Filtering &#8211; par ******* habitant *****</title>
		<link>https://www.smalsresearch.be/pii-filtering-fr/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Thu, 31 Oct 2024 16:24:12 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[audit]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[gdpr]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Security]]></category>
		<guid isPermaLink="false">/?p=21300</guid>

					<description><![CDATA[Comment protéger les données personnelles communiquées sans méfiance avec des agents conversationnels ? Le filtrage automatique peut partiellement aider, mais il ne s'agit pas d'une solution miracle.]]></description>
										<content:encoded><![CDATA[
<p><em>Dit artikel is ook beschikbaar <a href="/pii-filtering/" data-type="post" data-id="21217">in het Nederlands</a>.</em></p>



<p>Avec la popularité des applications d&#8217;IA dotées d&#8217;une interface conversationnelle, un &#8220;vieux casse-tête&#8221; refait surface : comment protéger les données personnelles communiquées, souvent sans méfiance, à un système automatisé de conversation ? Par extension, cette question se pose pour toute application où des données personnelles doivent être partagées avec des tiers. Les dépendances externes d&#8217;une application peuvent toutefois constituer un enchevêtrement complexe. Il n&#8217;est pas non plus toujours possible (ou économiquement viable) d&#8217;éviter les grands acteurs d&#8217;infrastructures informatiques d&#8217;IA &#8211; du moins pas si vous souhaitez rester à jour avec les dernières capacités de manière rentable.</p>



<p>Une solution possible est connue sous le nom de <em>PII Filtering</em>. En l&#8217;occurrence, PII est l&#8217;acronyme anglais de <em>Personal(ly) Identifiable/Identifying Information</em>, c&#8217;est-à-dire les informations par lesquelles une personne peut être identifiée. L&#8217;idée est assez simple&nbsp;: un filtre supplémentaire est placé devant l&#8217;application, qui élimine les informations à caractère personnel des données d&#8217;entrée, avant que celles-ci ne soient transmises à l&#8217;application. Si cela fonctionne bien, alors ce que l&#8217;application fait de ces données en coulisses n&#8217;a pas d&#8217;importance.</p>



<h2 class="wp-block-heading">PII vs. Personal Data</h2>



<p>Avant toute chose, il est crucial de comprendre que les PII ne peuvent être assimilées à des &#8220;Personal Data&#8221; telles que définies par le RGPD et d&#8217;autres législations européennes. Les PII sont un concept ancré dans le droit états-unien. Elles font généralement référence à un ensemble fini d&#8217;informations d&#8217;identification qui peuvent être utilisées dans le but de distinguer ou de confirmer l&#8217;identité d&#8217;un individu, comme les numéros de registre national, les adresses et les numéros de téléphone. Aux États-Unis, les réglementations sont souvent prescriptives à cet égard&nbsp;: par exemple, <a href="https://fr.wikipedia.org/wiki/Health_Insurance_Portability_and_Accountability_Act">HIPAA</a> (réglementation sur la protection des données relatives à la santé) comprend <a href="https://www.luc.edu/its/aboutus/itspoliciesguidelines/hipaainformation/the18hipaaidentifiers/">une liste de 18 identifiants</a> définis comme PII. Cela présente le grand avantage d&#8217;être relativement facile à implémenter : une fois que la liste est entièrement cochée, il n&#8217;y a plus guère de débat juridique possible.</p>



<p>En revanche, la <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">RGPD</a> européenne adopte une approche de principe : elle définit un concept plus large de <a href="https://gdpr-info.eu/art-4-gdpr/"><em>Personal Data</em></a> (données à caractère personnel). Ce concept englobe &#8220;toute information se rapportant à une personne physique identifiée ou identifiable&#8221;. Cela signifie que même des informations en apparence anodines, comme la couleur &#8220;rouge&#8221;, peuvent être considérées comme des données à caractère personnel si elles se rapportent, par exemple, à la couleur préférée d&#8217;une personne. Cette définition des données à caractère personnel dépendante du contexte rend toutefois pratiquement impossible le développement de détecteurs ou de filtres génériques et polyvalents pour ces données. Ce qui est considéré comme des données personnelles ou non doit être évalué au cas par cas. Les développeurs sont donc confrontés à une personnalisation plus importante qu&#8217;ils ne le souhaiteraient, mais les juristes, les DPO et les <a href="https://www.autoriteprotectiondonnees.be/">autorités de protection des données</a> ont également fort à faire avec de telles évaluations dans chaque pays de l&#8217;UE.</p>



<p>Ainsi, les solutions de filtrage des PII considérées comme conformes aux États-Unis risquent toujours de ne l&#8217;être que partiellement dans l&#8217;Union européenne. Étant donné que le terme <em>PII</em> semble s&#8217;être imposé sur le marché mondial, nous ferons dans le présent article uniquement référence aux PII. Gardez toujours à l&#8217;esprit que le <em>Personal Data</em> doit être le point de départ dans le contexte de l&#8217;UE.</p>



<h2 class="wp-block-heading"><strong>Détection et filtrage des PII</strong></h2>



<p>Afin de filtrer des informations textuelles, nous utilisons généralement des modèles techniques de <a href="https://fr.wikipedia.org/wiki/Reconnaissance_de_formes">reconnaissance de formes</a> et de <a href="https://fr.wikipedia.org/wiki/Traitement_automatique_des_langues">traitement automatique des langues (Natural Language Processing ou NLP)</a>. Ces modèles analysent les données non structurées, à la recherche de formes telles que des formats d&#8217;adresses e-mail ou des chaînes numériques similaires à un registre national ou encore à des numéros de téléphone, afin de les modifier ou de les anonymiser par la suite. En outre, des <a href="https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re">formes d&#8217;expression régulières (regex)</a> personnalisées sont souvent ajoutées afin de reconnaître les formes d&#8217;informations sensibles spécifiques à l&#8217;application en question.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2024/10/image.png"><img loading="lazy" decoding="async" width="523" height="217" src="/wp-content/uploads/2024/10/image.png" alt="Een voorbeeld van PII Filtering met NER in het Nederlands. Bron: pii-filter library (c) &quot;HabaneroCake&quot;, MIT license" class="wp-image-21255" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/image.png 523w, https://www.smalsresearch.be/wp-content/uploads/2024/10/image-300x124.png 300w" sizes="auto, (max-width: 523px) 100vw, 523px" /></a><figcaption class="wp-element-caption">Filtrage PII basé sur NER en néerlandais. Source: <a href="https://github.com/HabaneroCake/pii-filter/">pii-filter library</a> (c) &#8220;HabaneroCake&#8221;, MIT license</figcaption></figure>



<p>Un filtrage efficace des PII repose en grande partie sur la <a href="https://fr.wikipedia.org/wiki/Reconnaissance_d%27entit%C3%A9s_nomm%C3%A9es">reconnaissance d&#8217;entités nommées (Named Entity Recognition ou NER)</a>, une méthode NLP qui identifie les entités telles que les noms, les dates et les lieux dans un texte. Nous avons déjà publié des articles plus détaillés à ce sujet &#8211; voir les articles sur <a href="/facetten-van-natural-language-processing-deel-2/">NLP</a> et <a href="/named-entity-recognition-une-application-du-nlp-utile/">NER</a>.  L&#8217;essor de l&#8217;IA générative n&#8217;a pas encore changé grand-chose à la conception des techniques de NER. Aujourd&#8217;hui encore, de nombreux outils de filtrage de PII utilisent des outils NLP sous-jacents bien développés tels que <a href="https://www.nltk.org/">NLTK</a>, <a href="https://spacy.io/">SpaCy</a> ou <a href="https://flairnlp.github.io/">Flair</a>.</p>



<p>Toutefois, les PII peuvent également apparaître dans des images&nbsp;: scans de documents, photos de visages ou de plaques d&#8217;immatriculation, &#8230; Le filtrage de ces images nécessite une approche plus sophistiquée, car les données sensibles peuvent apparaître sous diverses formes, de notes écrites à la main à des reflets sur des photos. La <a href="https://fr.wikipedia.org/wiki/Reconnaissance_optique_de_caract%C3%A8res">reconnaissance optique de caractères (Optical Character Recognition ou OCR)</a> permet d&#8217;extraire le texte des images et de le convertir dans un format qui peut être analysé de la même manière que des données textuelles. Une fois le texte extrait, il est soumis au même processus de filtrage des PII à l&#8217;aide de techniques NLP. Des algorithmes de <a href="https://fr.wikipedia.org/wiki/D%C3%A9tection_d%27objet">reconnaissance d&#8217;objets</a> sont utilisés pour reconnaître les éléments visuels sensibles (tels que des visages ou des documents personnels) contenus dans l&#8217;image elle-même.</p>



<p>Une fois identifiées, vous devez décider de ce qu&#8217;il convient de faire avec les PII détectées. Les options possibles sont les suivantes&nbsp;:</p>



<ul class="wp-block-list">
<li>Remplacement/substitution par une autre valeur. Celle-ci peut éventuellement être créée à l&#8217;aide d&#8217;un <a href="https://faker.readthedocs.io/en/master/">outil de génération de données synthétiques</a>, de sorte que l&#8217;original est remplacé par une alternative d&#8217;apparence réaliste.</li>



<li>Masquage / obfuscation : remplacement par un caractère ou une barre. Cela peut être partiel, afin de ne pas perdre des informations plus générales utiles : par exemple, nous pouvons toujours voir que +32********* est un numéro de téléphone belge.</li>



<li>Suppression</li>



<li><a href="https://fr.wikipedia.org/wiki/Fonction_de_hachage_cryptographique">Hashage</a> (mieux encore avec <a href="https://fr.wikipedia.org/wiki/Salage_(cryptographie)">salage</a> en prévention des attaques par force brute)</li>



<li>Chiffrement, éventuellement <a href="https://en.wikipedia.org/wiki/Format-preserving_encryption">préservant le format des données</a></li>



<li>&#8230;</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h50_28.png"><img loading="lazy" decoding="async" width="1024" height="536" data-id="21266" src="/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png" alt="" class="wp-image-21266" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28.png 1052w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h51_34.png"><img loading="lazy" decoding="async" width="722" height="410" data-id="21264" src="/wp-content/uploads/2024/10/2024-10-28_21h51_34.png" alt="" class="wp-image-21264" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h51_34.png 722w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h51_34-300x170.png 300w" sizes="auto, (max-width: 722px) 100vw, 722px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h52_02.png"><img loading="lazy" decoding="async" width="736" height="374" data-id="21265" src="/wp-content/uploads/2024/10/2024-10-28_21h52_02.png" alt="" class="wp-image-21265" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h52_02.png 736w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h52_02-300x152.png 300w" sizes="auto, (max-width: 736px) 100vw, 736px" /></a></figure>
<figcaption class="blocks-gallery-caption wp-element-caption">Texte en néerlandais (à gauche) anonymisé par masquage (au centre) ou par substitution (à droite) à l&#8217;aide de <a href="https://language-tools.ec.europa.eu/NLPServices/NLP">l&#8217;outil UE NLP Service</a>. Notons que le texte anonymisé contient toujours des éléments de carrière uniques à partir desquels il est possible de déduire l&#8217;identité cachée. Texte source : <a href="https://pers.kortrijk.be/228363-kortrijk-rouwt-om-overlijden-martine-tanghe">Ville de Courtrai, communiqué de presse 23/07/2023</a></figcaption></figure>



<p>D&#8217;autres fonctions sont possibles pour les images, notamment&nbsp;:</p>



<ul class="wp-block-list">
<li>Flouter (blurring) ou d&#8217;autres filtres. Il convient de noter ici que certains filtres sont <a href="https://github.com/Y-Vladimir/SmartDeblur?tab=readme-ov-file">réversibles</a>.</li>



<li>Couvrir ou écraser, par exemple avec un rectangle noir.</li>



<li>&#8230;</li>
</ul>



<p>Le remplacement par une valeur alternative du même type peut toutefois créer des effets étranges, parce que l&#8217;entité n&#8217;est pas toujours estimée correctement ou parce que trop peu ou pas de contexte peut être pris en compte. Certains outils peuvent ainsi ne pas tenir compte du genre si un nom aléatoire doit être choisi pour remplacer un nom réel, alors qu&#8217;il peut être nécessaire de rester cohérent sur le plan grammatical ou sur celui du contenu. Il arrive également que des noms de lieux comme Saint-Nicolas soient anonymisés en Saint-Kevin, par exemple, parce que Nicolas est considéré comme un prénom. Les modèles de langage utilisés pour la NER ne sont donc certainement pas sans faille.</p>



<p>En théorie, il devrait être possible d&#8217;obtenir de meilleurs résultats en activant des LLM modernes comme le GPT-4 avec des requêtes construites de manière intelligente. Des mesures dans ce sens verront probablement le jour sous peu, mais aujourd&#8217;hui, les besoins en puissance de calcul, la consommation d&#8217;énergie et le coût sont encore trop élevés, et le temps de réponse trop lent, pour que l&#8217;on puisse également faire évoluer cette méthode.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h50_28.png"><img loading="lazy" decoding="async" width="1024" height="536" data-id="21266" src="/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png" alt="" class="wp-image-21266" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28.png 1052w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_22h24_02.png"><img loading="lazy" decoding="async" width="793" height="364" data-id="21271" src="/wp-content/uploads/2024/10/2024-10-28_22h24_02.png" alt="" class="wp-image-21271" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02.png 793w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02-300x138.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02-768x353.png 768w" sizes="auto, (max-width: 793px) 100vw, 793px" /></a></figure>
<figcaption class="blocks-gallery-caption wp-element-caption">Le même texte en néerlandais (à gauche) anonymisé par ChatGPT 4o (à droite). La requête demandait de &#8220;remplacer toutes les PII et les données personnelles, y compris les professions, les employeurs, les villes, les dates et les âges&#8221;. Notez que le texte résultant a également été réécrit. Pour y remédier, il faudrait développer et affiner la requête.</figcaption></figure>



<h2 class="wp-block-heading">Outils courants</h2>



<p>Les personnes qui recherchent des systèmes de filtrage de PII à grande échelle, et qui souhaitent pouvoir analyser des bases de données, des réseaux ou des systèmes de fichiers entiers, se retrouvent avec des outils du domaine de <a href="https://en.wikipedia.org/wiki/Data_loss_prevention_software"><em>Data Loss Prevention</em></a>. Ceux-ci devraient empêcher les PII de quitter l&#8217;entreprise sans les autorisations nécessaires. Vous trouverez une vue d&#8217;ensemble du marché en consultant <a href="https://www.gartner.com/reviews/market/data-loss-prevention">Gartner</a>. Les géants de l&#8217;internet proposent également des solutions à cette fin, telles que <a href="https://aws.amazon.com/fr/macie/">Amazon Macie</a>, <a href="https://cloud.google.com/security/products/sensitive-data-protection">Google SDP</a>, ou <a href="https://www.ibm.com/guardium">IBM Guardium</a>. Les techniques utilisées dans ces outils sont quelque peu liées à celles utilisées dans les enquêtes judiciaires &#8211; ce que l&#8217;on appelle l&#8217;eDiscovery, que nous avons <a href="/e-discovery/">déjà évoquée</a>.</p>



<p>Les créateurs d&#8217;applications sont plus susceptibles d&#8217;être intéressés par des outils sous forme de bibliothèques, de SDK ou d&#8217;API. Les projets intéressants sont les suivants&nbsp;:</p>



<ul class="wp-block-list">
<li>Pour le texte&nbsp;:
<ul class="wp-block-list">
<li><a href="https://microsoft.github.io/presidio/">Microsoft Presidio</a> (<a href="https://huggingface.co/spaces/presidio/presidio_demo">démo</a>) (également disponible sous la forme de <a href="https://microsoft.github.io/presidio/samples/docker/">Docker containers</a>), ou le service <a href="https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/quickstart?tabs=windows&amp;pivots=rest-api">PII detection</a> sur Azure</li>



<li><a href="https://docs.aws.amazon.com/comprehend/latest/dg/what-is.html">Amazon Comprehend</a> (<a href="https://ai-service-demos.go-aws.com/comprehend">démo</a>)</li>



<li>Les <a href="https://language-tools.ec.europa.eu/NLPServices">EU Language Services pour NLP</a> (login requis)&nbsp;: pour l&#8217;anonymisation des documents dans les langues de l&#8217;UE, basé sur le <a href="https://gitlab.com/MAPA-EU-Project/mapa_project">projet MAPA-EU</a>, qui peut également être utilisé via Docker Compose.</li>



<li><a href="https://github.com/tokern/piicatcher">PIICatcher</a> (pour les bases de données et les systèmes de fichiers)</li>
</ul>
</li>



<li>Pour les images&nbsp;:
<ul class="wp-block-list">
<li><a href="https://google.github.io/magritte/">Google Magritte</a>&nbsp;(pour les visages)</li>



<li><a href="https://github.com/facebookresearch/EgoBlur">Meta Research EgoBlur</a>&nbsp;(Pour les visages et les plaques d&#8217;immatriculation)</li>



<li><a href="https://github.com/redhuntlabs/Octopii">OctoPII</a> (Uniquement la détection, pas la modification. Pour les documents et les systèmes de fichiers, avec <a href="https://github.com/tesseract-ocr/tesseract">Tesseract</a> pour OCR engine)</li>
</ul>
</li>
</ul>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h36_03.png"><img loading="lazy" decoding="async" width="1024" height="401" src="/wp-content/uploads/2024/10/2024-10-28_21h36_03-1024x401.png" alt="Gezichts-anonymisering met Meta EgoBlur. " class="wp-image-21260" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-1024x401.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-300x117.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-768x300.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03.png 1268w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Anonymisation faciale avec Meta EgoBlur. Source&nbsp;: Nikhil Raina et.al.,&nbsp;<a href="https://arxiv.org/abs/2308.13093">“EgoBlur: Responsible Innovation in Aria”</a>, avec des illustrations du&nbsp;<a href="https://ai.meta.com/datasets/casual-conversations-v2-dataset/">CCV2 dataset</a> public.</figcaption></figure>



<p>De nouvelles recherches sont également en cours dans les universités. Par exemple, <a href="https://github.com/EdyVision/pii-codex">PII-Codex</a> est le résultat d&#8217;un <a href="https://joss.theoj.org/papers/10.21105/joss.05402">projet universitaire</a> qui présente une caractéristique intéressante : il utilise Presidio ou Comprehend, mais ajoute également son propre score de risque, qui devrait être en mesure d&#8217;indiquer dans quelle mesure la non modification des PII reconnues pourrait poser un risque (pour la protection de la vie privée). En outre, la plupart des outils permettent d&#8217;utiliser <a href="https://microsoft.github.io/presidio/analyzer/customizing_nlp_models/">vos propres modèles ou ceux des autres</a>. Vous pouvez éventuellement les <a href="https://huggingface.co/docs/transformers/training">peaufiner</a> vous-même pour la détection personnalisée d&#8217;entités, si vous disposez des données d&#8217;entraînement nécessaires à cet effet.</p>



<p>Si nous nous appuyons sur la NER ou la reconnaissance d&#8217;images pour la détection des PII, il est certain que certaines PII ne seront pas détectées et qu&#8217;à l&#8217;inverse, des éléments non PII pourraient également être classés à tort comme des PII. En effet, aucune de ces technologies ne garantit une précision de 100 %. Le taux de réussite variera également en fonction de la langue et du type d&#8217;entité que l&#8217;on tente de détecter. Il n&#8217;est jamais possible de garantir complètement le remplacement ou la suppression de chaque entité dans un document. Il est donc préférable de vérifier le résultat dans les cas où cela s&#8217;avère crucial.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Les solutions de filtrage de PII peuvent certainement contribuer à la protection de données à caractère personnel dans un contexte européen. Les techniques sont simples à comprendre et faciles à mettre en œuvre. Cependant, il n&#8217;y a jamais de garantie de détection totalement précise de toutes les données à caractère personnel et, dans la plupart des cas, leur utilisation devra donc faire partie d&#8217;un éventail plus large de mesures visant à promouvoir la conformité avec la RGPD et d&#8217;autres législations.</p>



<p>La technologie sous-jacente est &#8220;classique&#8221;, en ce sens que la NER et la reconnaissance d&#8217;images existent depuis longtemps et sont désormais bien développées. Aujourd&#8217;hui, elles bénéficient de l&#8217;attention portée à l&#8217;intelligence artificielle, et <a href="https://paperswithcode.com/task/named-entity-recognition-ner">toutes sortes d&#8217;étalons</a> leur permettent de rester à la pointe du progrès. Dans la pratique, nous constatons que le texte anonymisé qui en résulte peut parfois sembler un peu aliénant, car certains problèmes tout aussi classiques auxquels la NER est généralement confrontée ne sont pas encore totalement écartés.</p>



<p>______________________</p>



<p><em><em><em>Cette contribution a été soumise par Joachim Ganseman, consultant IT chez Smals Research. Elle a été rédigée en son nom propre et ne prend pas position au nom de Smals.</em></em></em></p>


]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PII Filtering &#8211; door ******* uit *****</title>
		<link>https://www.smalsresearch.be/pii-filtering/</link>
					<comments>https://www.smalsresearch.be/pii-filtering/#comments</comments>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Mon, 28 Oct 2024 15:37:54 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[audit]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[gdpr]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Security]]></category>
		<guid isPermaLink="false">/?p=21217</guid>

					<description><![CDATA[Hoe beschermen we persoonsgegevens die nietsvermoedend via chat worden meegedeeld? PII filtering kan gedeeltelijk helpen, maar is geen mirakeloplossing.]]></description>
										<content:encoded><![CDATA[
<p><em>Cet article est aussi disponible <a href="/pii-filtering-fr">en français</a>.</em></p>



<p>De populariteit van AI-toepassingen met chat-interface, doet een &#8220;oud zeer&#8221; opnieuw bovendrijven: hoe beschermen we persoonsgegevens die, vaak nietsvermoedend, via chat worden meegedeeld aan een geautomatiseerd systeem? Bij uitbreiding stelt zich deze vraag voor elke toepassing waar persoonsgebonden gegevens gedeeld moeten worden met derde partijen. De externe afhankelijkheden van een toepassing kunnen echter een ingewikkeld kluwen zijn. Het is ook niet altijd mogelijk (of economisch haalbaar) om de grote spelers op het vlak van cloud- en AI-diensten te ontwijken &#8211; toch niet als je mee wil zijn met de nieuwste mogelijkheden op een kostenefficiënte manier.</p>



<p>Een mogelijke oplossing staat bekend als <em>PII Filtering</em>. PII is daarbij het Engels acroniem voor <em>Personal(ly) Identifiable/Identifying Information</em>, i.e. de informatie waarmee iemand geïdentificeerd kan worden. Het idee is eenvoudig genoeg: we plaatsen een extra filter voor de applicatie, die de persoonlijke gegevens uit de input filtert, voordat die input aan de applicatie wordt doorgegeven. Als dat goed lukt, dan maakt het in principe niet meer uit wat de applicatie achter de schermen met die gegevens doet.</p>



<h2 class="wp-block-heading">PII vs. Personal Data</h2>



<p>Het is allereerst cruciaal om te begrijpen dat &#8220;PII&#8221; niet gelijkgesteld kan worden aan &#8220;Personal Data&#8221; zoals de GDPR en andere Europese wetgeving die definieert. PII is een concept dat geworteld is in Amerikaanse wetgeving. Het doelt meestal op een eindige set identificatiegegevens die kunnen worden gebruikt om de identiteit van een individu te onderscheiden of te achterhalen, zoals rijksregisternummers, adressen en telefoonnummers. Amerikaanse regelgeving is op dat vlak vaak prescriptief van aard: zo bevat de <a href="https://en.wikipedia.org/wiki/Health_Insurance_Portability_and_Accountability_Act">HIPAA</a> (privacywetgeving m.b.t. gezondheidsgegevens) een <a href="https://www.luc.edu/its/aboutus/itspoliciesguidelines/hipaainformation/the18hipaaidentifiers/">lijst met 18 identifiers</a> die als PII worden gedefinieerd. Dat heeft als groot voordeel dat het relatief gemakkelijk te implementeren is: wanneer het lijstje helemaal afgevinkt kan worden, is er ook juridisch weinig discussie meer.</p>



<p>Daarentegen hanteert de Europese <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">GDPR (AVG)</a> een principiële benadering: ze definieert een breder concept van <a href="https://gdpr-info.eu/art-4-gdpr/">Personal Data</a> (persoonsgegevens). Dat omvat &#8220;alle informatie met betrekking tot een geïdentificeerde of identificeerbare natuurlijke persoon&#8221;. Dit betekent dat zelfs schijnbaar onschuldige informatie, zoals de kleur &#8220;rood&#8221;, beschouwd kan worden als persoonsgegeven, als deze bijvoorbeeld betrekking heeft tot iemands lievelingskleur. Deze contextafhankelijke definitie van persoonsgegevens, maakt het echter ook nagenoeg onmogelijk om generieke, algemeen inzetbare detectoren of filters ervoor te ontwikkelen. Wat beschouwd wordt als persoonsgegeven of niet, moet geval per geval beoordeeld worden. Niet alleen ontwikkelaars worden daardoor geconfronteerd met meer maatwerk dan hen lief is, ook juristen, DPO&#8217;s en <a href="https://www.gegevensbeschermingsautoriteit.be/">Gegevensbeschermingsautoriteiten</a> hebben met zulke beoordelingen in elk EU-land de handen vol.</p>



<p>Oplossingen voor PII-filtering die voldoen voor gebruik in de VS, lopen dus altijd een risico om in de EU slechts gedeeltelijk tegemoet te komen aan de vereisten. Omdat de term <em>PII </em>echter algemeen ingang gevonden lijkt te hebben in de globale markt, spreken we verder in dit artikel enkel nog over PII. Houd wel permanent in het achterhoofd dat <em>Personal Data</em> altijd het uitgangspunt moet zijn in EU-context.</p>



<h2 class="wp-block-heading">PII Detectie en Filtering</h2>



<p>Om tekstuele input te filteren gebruiken we doorgaans <a href="https://en.wikipedia.org/wiki/Pattern_recognition">patroonherkenningstechnieken</a> en <a href="https://en.wikipedia.org/wiki/Natural_language_processing">Natural Language Processing (NLP)</a>-modellen. Deze modellen scannen ongestructureerde gegevens, op zoek naar patronen zoals e-mailformaten of numerieke reeksen die lijken op rijksregister- of telefoonnummers, om deze nadien te kunnen redigeren of anonimiseren. Daarnaast worden aangepaste <a href="https://en.wikipedia.org/wiki/Regular_expression">regex-patronen</a> vaak toegevoegd om vormen van gevoelige informatie te herkennen die specifiek zijn voor de betrokken toepassing.</p>



<figure class="wp-block-image aligncenter size-full"><a href="/wp-content/uploads/2024/10/image.png"><img loading="lazy" decoding="async" width="523" height="217" src="/wp-content/uploads/2024/10/image.png" alt="Een voorbeeld van PII Filtering met NER in het Nederlands. Bron: pii-filter library (c) &quot;HabaneroCake&quot;, MIT license" class="wp-image-21255" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/image.png 523w, https://www.smalsresearch.be/wp-content/uploads/2024/10/image-300x124.png 300w" sizes="auto, (max-width: 523px) 100vw, 523px" /></a><figcaption class="wp-element-caption">PII Filtering op basis van NER in het Nederlands. Bron: <a href="https://github.com/HabaneroCake/pii-filter/">pii-filter library</a> (c) &#8220;HabaneroCake&#8221;, MIT license</figcaption></figure>



<p>Effectieve PII-filtering steunt sterk op <a href="https://en.wikipedia.org/wiki/Named-entity_recognition">Named Entity Recognition (NER)</a>, een NLP-methode die entiteiten zoals namen, data en locaties in een tekst identificeert. We publiceerden daar eerder al over in meer detail &#8211; zie deze artikels over <a href="/facetten-van-natural-language-processing-deel-2/">NLP</a> en <a href="https://itdaily.be/blogs/software/named-entity-recognition-een-praktische-toepassing-van-natural-language-processing/">NER</a>. De opkomst van generatieve AI heeft aan de opzet van NER-technieken nog niet veel veranderd. Ook vandaag gebruiken veel PII filtering tools achterliggend goed ontwikkelde NLP-toolkits zoals <a href="https://www.nltk.org/">NLTK</a>, <a href="https://spacy.io/">SpaCy</a> of <a href="https://flairnlp.github.io/">Flair</a>.</p>



<p>PII kan echter ook in afbeeldingen opduiken: scans van documenten, foto&#8217;s van gezichten of nummerplaten, &#8230; Om dat weg te filteren is een geavanceerdere aanpak vereist, omdat de gevoelige gegevens kunnen verschijnen in uiteenlopende vormen, van handgeschreven notities tot reflecties in foto&#8217;s. <a href="https://en.wikipedia.org/wiki/Optical_character_recognition">Optical Character Recognition (OCR)</a> wordt gebruikt om tekst uit afbeeldingen te extraheren en deze om te zetten in een formaat dat op dezelfde manier kan worden geanalyseerd als tekstuele gegevens. Zodra de tekst is geëxtraheerd, ondergaat deze hetzelfde PII-filterproces met behulp van NLP-technieken. In gevallen waarin de afbeelding zelf gevoelige visuele elementen bevat (zoals gezichten of persoonlijke documenten), worden algoritmen voor <a href="https://en.wikipedia.org/wiki/Object_detection">beeldherkenning</a> gebruikt om dergelijke inhoud te herkennen.</p>



<p>Eenmaal geïdentificeerd, moet je besluiten wat er dient te gebeuren met de gedetecteerde PII. Opties kunnen zijn:</p>



<ul class="wp-block-list">
<li>Vervanging / substitutie door een andere waarde. Deze kan eventueel aangemaakt worden met een <a href="https://faker.readthedocs.io/en/master/">synthetic data tool</a>, zodat het origineel vervangen wordt door een realistisch ogend alternatief.</li>



<li>Masking / obfuscation: vervang door een karakter of balkje. Dit kan eventueel gedeeltelijk, om nuttige algemenere info niet te verliezen: zo zien we nog dat +32********* een Belgisch telefoonnummer is.</li>



<li>Verwijdering</li>



<li><a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">Hashing</a> (best met <a href="https://en.wikipedia.org/wiki/Salt_(cryptography)">salt</a> ter preventie van brute-force attacks)</li>



<li>Encryptie, eventueel <a href="https://en.wikipedia.org/wiki/Format-preserving_encryption">formaat-behoudend</a></li>



<li>&#8230;</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h50_28.png"><img loading="lazy" decoding="async" width="1024" height="536" data-id="21266" src="/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png" alt="" class="wp-image-21266" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28.png 1052w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h51_34.png"><img loading="lazy" decoding="async" width="722" height="410" data-id="21264" src="/wp-content/uploads/2024/10/2024-10-28_21h51_34.png" alt="" class="wp-image-21264" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h51_34.png 722w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h51_34-300x170.png 300w" sizes="auto, (max-width: 722px) 100vw, 722px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h52_02.png"><img loading="lazy" decoding="async" width="736" height="374" data-id="21265" src="/wp-content/uploads/2024/10/2024-10-28_21h52_02.png" alt="" class="wp-image-21265" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h52_02.png 736w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h52_02-300x152.png 300w" sizes="auto, (max-width: 736px) 100vw, 736px" /></a></figure>
<figcaption class="blocks-gallery-caption wp-element-caption">Nederlandstalige tekst (links) geanonymiseerd door maskeren (midden) of substitutie (rechts) met behulp van de <a href="https://language-tools.ec.europa.eu/NLPServices/NLP">EU NLP Service</a>. Merk op dat de geanonymiseerde tekst nog steeds unieke carrière-elementen vermeldt waaruit men de verborgen identiteit kan afleiden. Bron tekst: <a href="https://pers.kortrijk.be/228363-kortrijk-rouwt-om-overlijden-martine-tanghe">Stad Kortrijk, persbericht 23/07/2023</a> </figcaption></figure>



<p>Voor afbeeldingen zijn andere functies mogelijk, waaronder:</p>



<ul class="wp-block-list">
<li>Vervagen (blurring) of andere filters. Hierbij moet men er wel op letten dat sommige filters <a href="https://github.com/Y-Vladimir/SmartDeblur?tab=readme-ov-file">omkeerbaar</a> zijn.</li>



<li>Bedekken of overschrijven, bijvoorbeeld met een zwarte rechthoek.</li>



<li>&#8230;</li>
</ul>



<p>De vervanging door een alternatieve waarde van dezelfde soort kan echter soms ook voor vreemde effecten zorgen, omdat de entiteit niet altijd correct wordt ingeschat of omdat er te weinig of geen rekening gehouden kan worden met de context. Zo kan het zijn dat sommige tools geen acht slaan op het geslacht als een willekeurige naam moet worden gekozen om een echte naam te vervangen, terwijl dat wel nodig kan zijn om grammaticaal of inhoudelijk consistent te blijven. We zien soms ook plaatsnamen zoals Sint-Niklaas geanonymiseerd worden als pakweg Sint-Kevin, omdat Niklaas als naam werd aanzien. De taalmodellen gebruikt voor NER zijn dus zeker niet feilloos.</p>



<p>Het zou in theorie mogelijk moeten zijn om betere resultaten te halen door recente LLMs zoals GPT-4 in te schakelen met slim geconstrueerde prompts. Waarschijnlijk zullen er binnenkort wel stappen in die richting worden gezet, maar vandaag zijn de rekenkrachtvereisten, energieconsumptie en kostprijs daarvan nog te hoog, en de responstijd te traag, om dat ook schaalbaar te maken.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h50_28.png"><img loading="lazy" decoding="async" width="1024" height="536" data-id="21266" src="/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png" alt="" class="wp-image-21266" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-1024x536.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-300x157.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28-768x402.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h50_28.png 1052w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_22h24_02.png"><img loading="lazy" decoding="async" width="793" height="364" data-id="21271" src="/wp-content/uploads/2024/10/2024-10-28_22h24_02.png" alt="" class="wp-image-21271" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02.png 793w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02-300x138.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_22h24_02-768x353.png 768w" sizes="auto, (max-width: 793px) 100vw, 793px" /></a></figure>
<figcaption class="blocks-gallery-caption wp-element-caption">Dezelfde Nederlandstalige tekst (links) geanonymiseerd door ChatGPT 4o (rechts). In de prompt werd gevraagd &#8220;vervang alle PII en persoonsgegevens, ook de beroepen, werkgevers, steden, datums en leeftijden.&#8221; Merk op dat de resulterende tekst ook herschreven werd. Om dat tegen te gaan zou verdere uitbreiding en verfijning van de prompt nodig zijn.</figcaption></figure>



<h2 class="wp-block-heading">Tools of the trade</h2>



<p>Wie op zoek gaat naar grootschalige PII Filtering systemen, en volledige databases, netwerken of filesystems wil kunnen scannen, komt terecht bij <a href="https://en.wikipedia.org/wiki/Data_loss_prevention_software">Data Loss Prevention</a> tools. Deze moeten verhinderen dat PII het bedrijf verlaat zonder de nodige toelatingen. Voor een marktoverzicht verwijzen we naar <a href="https://www.gartner.com/reviews/market/data-loss-prevention">Gartner</a>. Ook de internetgiganten bieden daarvoor oplossingen aan, zoals <a href="https://aws.amazon.com/macie/">Amazon Macie</a>, <a href="https://cloud.google.com/security/products/sensitive-data-protection">Google SDP</a>, of <a href="https://www.ibm.com/guardium">IBM Guardium</a>. De daarbij gebruikte technieken zijn enigszins verwant met diegene gebruikt bij forensisch onderzoek &#8211; de zogenaamde eDiscovery, waarover we ook al <a href="/e-discovery/">eerder schreven</a>.</p>



<p>Applicatiebouwers zijn waarschijnlijk eerder geïnteresseerd in tools in de vorm van bibliotheken, SDK&#8217;s of API&#8217;s. Interessante projecten zijn:</p>



<ul class="wp-block-list">
<li>Voor tekst:
<ul class="wp-block-list">
<li><a href="https://microsoft.github.io/presidio/">Microsoft Presidio</a> (<a href="https://huggingface.co/spaces/presidio/presidio_demo">demo</a>) (ook beschikbaar als <a href="https://microsoft.github.io/presidio/samples/docker/">Docker containers</a>), of de <a href="https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/quickstart?tabs=windows&amp;pivots=rest-api">PII detection</a> dienst op Azure</li>



<li><a href="https://docs.aws.amazon.com/comprehend/latest/dg/what-is.html">Amazon Comprehend</a> (<a href="https://ai-service-demos.go-aws.com/comprehend">demo</a>)</li>



<li>De <a href="https://language-tools.ec.europa.eu/NLPServices">EU Language Services voor NLP</a> (inloggen vereist): voor anonymisering van documenten in EU-talen, gebaseerd op het <a href="https://gitlab.com/MAPA-EU-Project/mapa_project">MAPA-EU project</a> dat ook via Docker Compose gebruikt kan worden.</li>



<li><a href="https://github.com/tokern/piicatcher">PIICatcher</a> (voor databases en filesystems)</li>
</ul>
</li>



<li>Voor afbeeldingen:
<ul class="wp-block-list">
<li><a href="https://google.github.io/magritte/">Google Magritte</a> (voor gezichten)</li>



<li><a href="https://github.com/facebookresearch/EgoBlur">Meta Research EgoBlur</a> (voor gezichten en nummerplaten)</li>



<li><a href="https://github.com/redhuntlabs/Octopii">OctoPII</a> (enkel detectie en geen redactie. Voor documenten en filesystems, met <a href="https://github.com/tesseract-ocr/tesseract">Tesseract</a> als OCR engine)</li>
</ul>
</li>
</ul>



<figure class="wp-block-image aligncenter size-large"><a href="/wp-content/uploads/2024/10/2024-10-28_21h36_03.png"><img loading="lazy" decoding="async" width="1024" height="401" src="/wp-content/uploads/2024/10/2024-10-28_21h36_03-1024x401.png" alt="Gezichts-anonymisering met Meta EgoBlur. " class="wp-image-21260" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-1024x401.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-300x117.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03-768x300.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/10/2024-10-28_21h36_03.png 1268w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Gezichts-anonymisering met Meta EgoBlur. Bron: Nikhil Raina et.al., <a href="https://arxiv.org/abs/2308.13093">&#8220;EgoBlur: Responsible Innovation in Aria&#8221;</a>, met foto&#8217;s uit de publieke <a href="https://ai.meta.com/datasets/casual-conversations-v2-dataset/">CCV2 dataset</a>.</figcaption></figure>



<p>Ook in academia wordt er verder onderzoek gedaan. Zo is <a href="https://github.com/EdyVision/pii-codex">PII-Codex</a> het resultaat van een <a href="https://joss.theoj.org/papers/10.21105/joss.05402">universitair project</a>, met een interessante feature: achterliggend maakt het gebruik van Presidio of Comprehend, maar het voegt ook een eigen risico-score toe, die moet kunnen aangeven in welke mate het niet-redigeren van de herkende PII een (privacy-)risico zou kunnen inhouden. Daarnaast laten de meeste tools ook toe om <a href="https://microsoft.github.io/presidio/analyzer/customizing_nlp_models/">andere of eigen modellen</a> in te pluggen. Deze kan je eventueel zelf <a href="https://huggingface.co/docs/transformers/training">gefinetuned</a> hebben voor detectie van custom entiteiten, als je daarvoor de nodige trainingsdata hebt.</p>



<p>Als we vertrouwen op NER of beeldherkenning voor PII-detectie, dan kunnen we er zeker van zijn dat sommige PII niet gedetecteerd zal worden, en dat ook andersom niet-PII foutief als PII aangemerkt kan worden. Geen van deze technologieën garandeert immers 100% accuraatheid. Het succespercentage zal ook variëren afhankelijk van de taal en het entiteitstype dat men probeert te detecteren. Volledige vervanging of verwijdering van elke entiteit in een document kan nooit worden gegarandeerd. Daar waar dat cruciaal is, wordt het resultaat achteraf dus best nog gecontroleerd.</p>



<h2 class="wp-block-heading">Conclusie</h2>



<p>Oplossingen voor PII-filtering kunnen in Europese context zeker bijdragen aan de bescherming van persoonsgegevens. De techniek is eenvoudig te begrijpen en gemakkelijk inzetbaar. Er is echter nooit een garantie op volledige accurate detectie van alle persoonsgegevens, en dus zal hun gebruik in de meeste gevallen een onderdeel moeten zijn van een ruimere waaier aan maatregelen om <em>compliance </em>met GDPR en andere wetgeving te bevorderen.</p>



<p>De achterliggende technologie is &#8220;klassiek&#8221;, in de zin dat NER en beeldherkenning al lang bestaan en ondertussen goed ontwikkeld zijn. Vandaag profiteren ze mee van de aandacht voor artificiële intelligentie, en <a href="https://paperswithcode.com/task/named-entity-recognition-ner">allerlei benchmarks</a> laten toe om de state-of-the-art op te volgen. In de praktijk merken we wel dat de resulterende geanonymiseerde tekst soms wat bevreemdend kan overkomen, omdat enkele al even klassieke problemen waar NER typisch mee kampt, nog altijd niet helemaal van de baan zijn.</p>



<p>______________________</p>



<p><em>Dit is een ingezonden bijdrage van Joachim Ganseman, IT consultant bij Smals Research. &nbsp;Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.smalsresearch.be/pii-filtering/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Premier tour d&#8217;horizon de l&#8217;AI Act</title>
		<link>https://www.smalsresearch.be/premier-tour-dhorizon-de-lai-act/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Wed, 17 Jul 2024 15:14:57 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[audit]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[sustainability]]></category>
		<guid isPermaLink="false">/?p=20917</guid>

					<description><![CDATA[Nous vous en disons plus sur l'AI Act européen, dernière pierre angulaire d'une série d'initiatives législatives à grande échelle destinées à réglementer l'économie numérique en Europe.]]></description>
										<content:encoded><![CDATA[
<p><em>Dit artikel is ook beschikbaar <a href="/een-eerste-kennismaking-met-de-ai-act/">in het Nederlands</a>.</em></p>



<p><em>Note&nbsp;: il s&#8217;agit d&#8217;un article de vulgarisation consacré à une réglementation future, basé sur la </em><a href="https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=OJ%3AL_202401689"><em>publication officielle du 12/07/2024</em></a><em>. Adressez-vous toujours à un·e juriste pour obtenir un avis juridique professionnel.</em></p>



<p>L&#8217;<a href="https://digital-strategy.ec.europa.eu/fr/policies/regulatory-framework-ai">AI Act européen</a> (en français <em>le règlement sur l&#8217;intelligence artificielle</em>) est une des pierres angulaires d&#8217;une série d&#8217;initiatives législatives à grande échelle destinées à réglementer l&#8217;économie numérique en Europe. Il vient ainsi compléter la législation antérieure relative à certains aspects de l&#8217;intelligence artificielle, comme le <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">RGPD</a>, le <a href="https://digital-strategy.ec.europa.eu/en/policies/digital-services-act-package">Digital Services Act (DSA) et le Digital Markets Act (DMA)</a>, le <a href="https://digital-strategy.ec.europa.eu/en/policies/data-act">Data Act</a>, le <a href="https://digital-strategy.ec.europa.eu/en/policies/data-governance-act">Data Governance Act</a>, le <a href="https://digital-strategy.ec.europa.eu/en/policies/european-chips-act">CHIPS Act</a> et le <a href="https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act">Cyber Resilience Act</a> en cours d&#8217;élaboration. Après de longues négociations, l&#8217;AI Act a été approuvé par le Parlement européen en mars 2024 et par le Conseil européen en mai 2024. La publication au Journal officiel de l&#8217;Union européenne, que l&#8217;on peut appeler Moniteur européen, a eu lieu le <a href="https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=OJ%3AL_202401689">12 juillet 2024</a>. Les premières règles entreront en vigueur début 2025. Vous pouvez également consulter <a href="https://artificialintelligenceact.eu/developments/">cette chronologie</a>.</p>



<h2 class="wp-block-heading">Un RGPD bis&nbsp;?</h2>



<p>Le texte intégral de l&#8217;AI Act, y compris l&#8217;ensemble des préliminaires et annexes, comprend <a href="https://eur-lex.europa.eu/legal-content/FR/TXT/PDF/?uri=OJ:L_202401689">144 pages</a>. Fort heureusement, de <a href="https://artificialintelligenceact.eu/high-level-summary/">bons résumés</a> sont déjà disponibles <a href="https://www.stibbe.com/publications-and-insights/the-eu-artificial-intelligence-act-our-16-key-takeaways">ici et là</a>. Il est ainsi presque deux fois plus long que le <a href="https://eur-lex.europa.eu/legal-content/FR/TXT/PDF/?uri=CELEX:32016R0679">RGPD</a> qui ne fait, lui, &#8220;que&#8221; 88 pages. L&#8217;impact de ce dernier est énorme : toutes les organisations traitant des données à caractère personnel &#8211; il suffit d&#8217;avoir une administration du personnel ou un fichier de clients &#8211; se sont en effet vues confrontées aux exigences relatives aux délégués à la protection des données, aux registres de traitement et aux bases juridiques du traitement des données. Chaque pays a également dû mettre en place une  <a href="https://www.autoriteprotectiondonnees.be/">Autorité de protection des données</a> habilitée à <a href="https://www.dailybits.be/item/overzicht-gdpr-boetes-rechtszaken/#BE">infliger des amendes en cas d&#8217;infraction</a>.</p>



<p>Le RGPD s&#8217;est également accompagné d&#8217;une certaine confusion, notamment par son utilisation fréquente de termes ouverts à l&#8217;interprétation (&#8220;approprié&#8221;, &#8220;adéquat&#8221;, &#8220;adapté&#8221;, &#8220;suffisant&#8221;&#8230;).<br>La nécessité de les concrétiser à nouveau pour chaque cas d&#8217;espèce alimente ce que l&#8217;on peut aujourd&#8217;hui appeler une petite industrie juridique. L&#8217;AI Act vise à fournir un peu plus d&#8217;indications, en revêtant une forme plus technique. Il comporte ainsi une liste d&#8217;annexes avec des énumérations pratiques des attentes en matière de documentation, de conformité, de transparence, etc.</p>



<p>L&#8217;AI Act est parti d&#8217;une proposition plus compacte de <a href="https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX%3A52021PC0206">125 pages (annexes incluses)</a>. Au cours des négociations cependant, on a assisté à l&#8217;essor fulgurant de l&#8217;IA générative et des grands modèles de langage. Cette nouvelle donne a nécessité la révision et l&#8217;ajout de certains éléments, tels qu&#8217;un nouveau chapitre (5) entièrement consacré aux modèles d&#8217;IA à usage général, parmi lesquels on compte les grands modèles de langage. Quant à certaines sections, on peut se demander ce qu&#8217;elles viennent faire dans l&#8217;AI Act, notamment un système de &#8220;bacs à sable réglementaires de l&#8217;IA&#8221; (article 57) qui doit permettre aux régulateurs de faciliter l&#8217;innovation. Certains articles sont formulés de manière plutôt énigmatique, comme la section dédiée aux &#8220;organismes d’évaluation de la conformité notifiés&#8221; (article 29), qui ne sont <a href="https://www.hiig.de/en/eu-ai-act/">ni plus ni moins que des auditeurs</a>. Des <a href="https://www.euractiv.com/section/digital/news/the-long-and-winding-road-to-implement-the-ai-act/">voix critiques</a> se font donc entendre, craignant que la somme de mesures qui en résulte ne débouche avant tout sur un véritable imbroglio.</p>



<h2 class="wp-block-heading">AI Act &#8211; Fondamentaux</h2>



<p>L&#8217;AI Act s&#8217;adresse aux développeurs et aux fournisseurs d&#8217;IA, et ce uniquement lorsqu&#8217;ils publient des systèmes d&#8217;IA et les mettent à la disposition de tiers. Tous les développements et tests internes préalables sont explicitement exemptés (article 2 §8). L&#8217;AI Act ne s&#8217;applique pas non plus aux activités personnelles auxquelles vous vous adonnez dans un contexte non professionnel (article 2 §10). De même, la recherche scientifique (article 2 §6) et les applications militaires (article 2 §3) ne sont pas concernées. Bien évidemment, cela ne signifie pas que tout est permis dans tous ces cas.<br>Il va de soi que d&#8217;autres législations existantes restent en vigueur. Les droits des citoyens étaient déjà protégés par <a href="https://gdpr-info.eu/art-22-gdpr/">l&#8217;article 22 du RGPD entre autres</a>, tandis que la législation sur les droits d&#8217;auteur continue de protéger les auteurs.</p>



<p>Par ailleurs, la définition de l&#8217;IA utilisée est particulièrement large et empruntée à l&#8217;<a href="https://oecd.ai/en/wonk/ai-system-definition-update">OCDE</a>&nbsp;: en résumé, &#8220;un système IA [&#8230;] déduit, à partir des entrées, la manière de générer des sorties [&#8230;]&#8221; (article 3 + considérant 12). La quasi-totalité de l&#8217;apprentissage automatique entre dans ce cadre. Dans d&#8217;autres définitions, on lit parfois que l&#8217;IA comporte un aspect cognitif (quelque chose doit être &#8220;reconnu&#8221;), mais il n&#8217;en est pas fait mention ici. Il n&#8217;est pas non plus fait mention de techniques spécifiques&nbsp;: tout ce qui apprend de manière adaptative ou peut réagir de manière quelque peu autonome à l&#8217;environnement est presque toujours inclus. Il s&#8217;agit donc également des systèmes que vous connaissez depuis des années, sans vous rendre compte qu&#8217;ils reposent sur l&#8217;intelligence artificielle, tels que les filtres antispam, les recommandations sur les sites web, voire les prévisions météorologiques.</p>



<p>L&#8217;AI Act définit d&#8217;abord et surtout une liste de pratiques interdites (article 5), qui prendra effet dès le début de l&#8217;année 2025. Cette liste est exhaustive, ce qui signifie en principe que tout ce qui n&#8217;est pas explicitement interdit est autorisé (sauf dispositions contraires prévues par d&#8217;autres lois). Aussi est-il intéressant d&#8217;examiner ce qui figure et ce qui ne figure pas dans cette liste d&#8217;interdictions, ainsi que les dispositions supplémentaires qui s&#8217;y rapportent. On découvre ainsi que&nbsp;:</p>



<ul class="wp-block-list">
<li>§1(f)&nbsp;: L&#8217;interdiction de la reconnaissance des émotions ne mentionne que le lieu de travail et l&#8217;enseignement.</li>



<li>§1(g)&nbsp;: L&#8217;interdiction des systèmes d&#8217;IA biométriques ne mentionne que la déduction automatique concernant la race, la sexualité, l&#8217;affiliation à une organisation syndicale, la religion, les convictions politiques et philosophiques.</li>



<li>§1(e)&nbsp;: L&#8217;interdiction de la reconnaissance faciale ne concerne que les systèmes basés sur ce qu&#8217;on appelle &#8220;moissonnage non ciblé&#8221;.</li>
</ul>



<p>Elle est donc plus nuancée qu&#8217;une liste d&#8217;interdictions générales, car le contexte et l&#8217;objectif interviennent également. La reconnaissance des émotions dans les jeux vidéo, par exemple, reste ainsi autorisée. Les considérants 15 à 17 précisent que l&#8217;IA biométrique reste autorisée pour la vérification d&#8217;identité et l&#8217;authentification. Parallèlement, des exceptions sont prévues entre autres pour l&#8217;assistance médicale et la lutte contre la criminalité, bien que ces exceptions soient soumises à un contrôle strict (article 5, §2-§7), y compris une liste des infractions pénales qui entrent en ligne de compte (annexe 2).</p>



<p>Les systèmes qui assurent la sécurité des utilisateurs ou qui sont énumérés à l&#8217;annexe 3 sont des systèmes à haut risque (article 6). Il s&#8217;agit principalement de systèmes susceptibles d&#8217;avoir un impact majeur sur les libertés, la vie, la carrière ou la santé d&#8217;un individu. Bien que cette section de l&#8217;AI Act n&#8217;entrera en vigueur qu&#8217;à l&#8217;été 2026, il convient de noter qu&#8217;il subsiste des lacunes à combler. Par exemple, la Commission doit encore fournir des lignes directrices précisant l&#8217;interprétation de cet article (article 6 §5) et se réserve le droit d&#8217;apporter des modifications même après coup (article 6 §6-§8, article 7).</p>



<h2 class="wp-block-heading">AI Act &#8211; Obligations</h2>



<p>Quiconque souhaite construire ou a construit un système à haut risque devra se conformer à une série d&#8217;obligations, qui doivent notamment permettre aux autorités compétentes d&#8217;intervenir en cas de non-respect. Les développeurs de systèmes à haut risque devront adopter certaines pratiques, notamment&nbsp;:</p>



<ul class="wp-block-list">
<li>Un système itératif de gestion des risques (article 9), qui doit permettre d&#8217;identifier et d&#8217;évaluer les risques et d&#8217;atténuer les abus potentiels à l&#8217;avance. Le texte est relativement peu concret&nbsp;: il parle de &#8220;risques raisonnablement prévisibles&#8221; et de &#8220;mesures appropriées&#8221; sans autre précision. Ceci fera donc encore l&#8217;objet de discussions, mais dans la pratique, on peut déjà aujourd&#8217;hui se contenter en partie des normes récemment élaborées à cette fin, telles que la norme <a href="https://www.iso.org/standard/81230.html">ISO/IEC 42001</a>. Étant entendu qu&#8217;elle n&#8217;est pas explicitement conçue pour la loi sur l&#8217;IA Act, des mesures supplémentaires peuvent s&#8217;imposer.</li>



<li>La gestion de données de qualité (article 10), qui se résume en grande partie à la transparence sur l&#8217;origine, les limites, les marges d&#8217;erreur et la représentativité. L&#8217;utilisation de <a href="https://arxiv.org/abs/1803.09010">Data Sheets</a> (fiches de données), dont c&#8217;est l&#8217;objectif, est devenue populaire dans le secteur au cours des dernières années.</li>



<li>Fournir une documentation technique conforme aux exigences de l&#8217;annexe 4 (annexe 11 pour l&#8217;IA à usage général). Ceci est quelque peu analogue aux <a href="https://huggingface.co/docs/hub/model-cards">Model Cards</a> (cartes modèles) que l&#8217;on peut trouver sur le HuggingFace Hub, bien que la Commission européenne ne se contente pas de listes cochées et exige plus de détails, y compris sur la surveillance et le contrôle pendant la durée de vie du système.</li>



<li>L&#8217;enregistrement (article 12) ainsi que la transparence et la fourniture d’informations aux utilisateurs (article 13).</li>



<li>Le contrôle humain pendant la durée de vie du système (article 14). Si l&#8217;article 22 du RGPD en faisait déjà un droit civil, l&#8217;AI Act impose aux développeurs de prendre les mesures nécessaires à cette fin. Par exemple, il devra toujours être possible d’ignorer, de remplacer ou d&#8217;arrêter le système d&#8217;IA (article 14 §4 (d-e)).</li>



<li>Prendre des mesures &#8220;appropriées&#8221; en matière de cybersécurité, de robustesse et d&#8217;exactitude (article 15). Cet article reste lui aussi relativement vague à l&#8217;heure actuelle et fait référence à l&#8217;intention de la Commission de soutenir le développement des étalonnages nécessaires.</li>
</ul>



<p>Quiconque publie, met à disposition, incorpore dans son propre produit, importe ou distribue un système à haut risque devra prendre des mesures similaires, notamment&nbsp;:</p>



<ul class="wp-block-list">
<li>Vérifier et prouver la conformité du système (article 16 §e-l, articles 40-47), établir une déclaration de conformité (annexe 5) et obtenir le marquage CE (article 48).&nbsp;</li>



<li>Utiliser un système de gestion de la qualité (article 17).</li>



<li>Conserver la documentation nécessaire pendant 10 ans après la mise en service (article 18).</li>



<li>Coopérer avec les autorités compétentes (article 21).</li>



<li>Enregistrer le système (article 49) dans une base de données européenne dédiée (article 71).</li>



<li>Désigner une personne de contact ou un représentant pour tout ce qui précède (article 22).</li>



<li>Mettre en place la surveillance nécessaire et agir en cas de problème (article 26 §5 et articles 72-73), notamment en informant l&#8217;autorité compétente.</li>
</ul>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg"><img loading="lazy" decoding="async" width="606" height="335" src="/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg" alt="" class="wp-image-20899" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg 606w, https://www.smalsresearch.be/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759-300x166.jpg 300w" sizes="auto, (max-width: 606px) 100vw, 606px" /></a><figcaption class="wp-element-caption">Cycle de vie des systèmes d&#8217;IA à haut risque dans le cadre de l&#8217;AI Act. Image (c) Union Européenne, CC-BY-4.0</figcaption></figure>



<p>Par analogie avec l&#8217;analyse d&#8217;impact relative à la protection des données du RGPD, certaines organisations, dont toutes les autorités publiques et les organisations de service public, devront réaliser une analyse d&#8217;impact sur les droits fondamentaux (<a href="https://www.technologyslegaledge.com/2024/03/fundamental-rights-impact-assessments-under-the-eu-ai-act-who-what-and-how/">Fundamental Rights Impact Assessment ou FRIA</a>) dont les résultats devront être communiqués aux <a href="https://single-market-economy.ec.europa.eu/single-market/goods/building-blocks/market-surveillance/organisation_en">régulateurs du marché compétents</a> (article 27). L&#8217;AI Office européen est déjà chargé de développer les questionnaires automatisés nécessaires à l&#8217;acquittement de cette obligation (article 27 §5).</p>



<p>On en oublierait presque que la grande majorité des systèmes d&#8217;IA sont simplement des systèmes à faible risque. À cet égard, l&#8217;AI Act est assez succinct&nbsp;: ils doivent satisfaire à des exigences minimales de transparence uniquement pour des applications spécifiques (article 50). Ainsi, l&#8217;utilisateur final doit toujours savoir qu&#8217;il interagit avec un système d&#8217;IA, et les résultats générés artificiellement doivent être clairement identifiés comme tels. La mainmise redoutée sur l&#8217;ensemble de l&#8217;industrie de l&#8217;IA est donc toute relative.</p>



<h2 class="wp-block-heading">IA à usage général</h2>



<p>Le développement récent de l&#8217;IA générative à usage général pour le texte et les images a nécessité l&#8217;ajout d&#8217;une catégorie distincte de systèmes, à savoir l&#8217;IA à usage général. La Commission européenne considère que ce type d&#8217;IA, indépendamment d&#8217;un éventuel risque élevé en matière de droits civils, peut également présenter un risque systémique (article 51). Le bien-fondé ou non de cette position fait l&#8217;objet d&#8217;un <a href="https://quillette.com/2024/07/02/superintelligence-10-years-on-nick-bostrom-ai-safety-agi/">débat acharné </a>dans les cercles techniques et philosophiques, mais l&#8217;UE adopte une approche prudente et prévoit un bâton juridique.</p>



<p>La Commission européenne se donne la liberté de déterminer les systèmes qui présentent un tel risque (article 51 §1). Bien qu&#8217;elle affirme appliquer des critères objectifs pour ce faire (annexe 13), il n&#8217;y a pas de véritable formule. Néanmoins, l&#8217;article 51 §2 fixe étonnamment une limite très concrète, à savoir qu&#8217;à partir du moment où son entraînement requiert une puissance de calcul de 10<sup>25</sup> FLOPS, un modèle d’IA à usage général est par définition considéré comme présentant un risque systémique. Cela correspond approximativement à un temps d&#8217;entraînement d&#8217;un an sur un cluster de 4000 GPU de type Nvidia RTX4090 (avec une puissance de calcul de 82&#215;10<sup>12</sup> FLOPS). Pour éviter que tout cela ne devienne obsolète demain, la Commission se réserve le droit d&#8217;adapter ces valeurs à l&#8217;avenir en fonction des évolutions du domaine (article 51 §3).</p>



<p>Outre les exigences minimales de l&#8217;article 50 et indépendamment de la classification des risques, l&#8217;IA à usage général est soumise à son propre ensemble d&#8217;exigences en matière de documentation technique (article 53, annexe 11), qui seront un peu élargies en présence d&#8217;un risque systémique (article 55). Les constructeurs de modèles d’IA à usage général sans risque systémique publiés sous licence libre sont exemptés de certaines obligations (article 53 §2, voir également les considérants 102 à 104) et ne sont pas non plus tenus de désigner une personne de contact ou un représentant (article 54 § 6).</p>



<h2 class="wp-block-heading">AI Office (Bureau de l&#8217;IA)</h2>



<p>L&#8217;AI Act devra également être appliqué. Un rôle majeur dans ce cadre sera joué par <a href="https://digital-strategy.ec.europa.eu/en/policies/ai-office">l&#8217;AI Office</a> (<em>Bureau de l&#8217;IA</em>, article 64), qui devrait être à l&#8217;AI Act ce que le <a href="https://www.edps.europa.eu/">Contrôleur européen de la protection des données</a> est au RGPD. L&#8217;AI Office est actuellement mis en place à grande vitesse, les premières dispositions entrant en vigueur début 2025. Outre la responsabilité de compléter une série d&#8217;articles en suspens de l&#8217;IA Act, l&#8217;AI Office se verra confier la compétence exclusive de la surveillance de l&#8217;IA à usage général (article 75).</p>



<p><a href="https://digital-strategy.ec.europa.eu/"></a>En pratique, l&#8217;AI Office fera partie de la <a href="https://digital-strategy.ec.europa.eu/">DG CONNECT</a>, commencera avec 140 collaborateurs et sera dirigé par <a href="https://www.euronews.com/next/2024/05/29/ai-office-set-up-announced-lucilla-sioli-to-be-in-charge">Lucilla Sioli</a>. Il sera soutenu dans son fonctionnement par le <a href="https://algorithmic-transparency.ec.europa.eu/">Centre européen pour la transparence algorithmique (ECAT)</a>, un <a href="https://digital-strategy.ec.europa.eu/en/news/commission-hosts-high-level-meeting-upcoming-eus-ai-board-drive-ai-act-implementation-forward">Comité AI</a> (article 65), un forum consultatif des parties prenantes (article 67) et un groupe scientifique d’experts indépendants (article 68).</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg"><img loading="lazy" decoding="async" width="800" height="592" src="/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg" alt="" class="wp-image-20902" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg 800w, https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002-300x222.jpg 300w, https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002-768x568.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-element-caption">Organigramme de l&#8217;AI Office de l&#8217;UE. Image (c) Union Européenne, CC-BY-4.0</figcaption></figure>



<p>Des régulateurs doivent également être désignés au niveau national (article 70). Ils devront travailler en étroite collaboration avec l&#8217;AI Office de l&#8217;UE et avec les régulateurs industriels et sectoriels existants, qui aujourd&#8217;hui sont déjà responsables du marquage CE, par exemple. <a href="https://www.autoriteitpersoonsgegevens.nl/actueel/ap-en-rdi-toezicht-op-ai-systemen-vraagt-samenwerking-en-moet-snel-geregeld-worden">Aux Pays-Bas, l&#8217;Autoriteit Persoonsgegevens joue clairement un rôle de pionnier </a>dans la mise sur pied d&#8217;une autorité néerlandaise de l&#8217;IA, qui sera probablement établie dans le giron de l&#8217;Autoriteit Persoonsgegevens. En Belgique, la situation reste <a href="https://data-en-maatschappij.ai/nieuws/gastblog-waar-blijft-de-belgische-toezichthouder-voor-algoritmes">calme</a>, même si le temps presse. En effet, on ne peut pas non plus engager n&#8217;importe qui pour occuper ces fonctions assez spécialisées.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Il est important de retenir que l&#8217;AI Act n&#8217;impose aucune restriction aux systèmes d&#8217;IA à faible risque, à l&#8217;exception de l&#8217;IA à usage général qui requiert la transparence nécessaire. Ce n&#8217;est que pour les systèmes à risques élevés ou systémiques et mis en production qu&#8217;interviennent des exigences strictes et la nécessité de se conformer aux réglementations pertinentes. Même dans ce cas, de nombreuses mesures d&#8217;atténuation offrent une marge de manœuvre supplémentaire au développement interne, aux initiatives open source, à la science, à la défense, etc.</p>



<p>Dans une certaine mesure, l&#8217;AI Act se veut concret, par une énumération détaillée des attentes et la mention de diverses précisions dans les considérants et les annexes. Il y parvient en partie et devient ainsi assez technique, de sorte qu&#8217;un juge concerné devra apprendre ce que sont les FLOPS. Parallèlement, il subsiste de nombreuses lacunes à combler et il reste à voir où le nouvel AI Office placera la barre dans les futures Commissions. La possibilité de modifier ultérieurement l&#8217;IA Act a été envisagée ici et là. La version actuelle de l&#8217;IA Act ne sera donc certainement pas la dernière.</p>



<p>Enfin, en Belgique, il ne s&#8217;agit pas d&#8217;attendre trop longtemps pour désigner et organiser le(s) régulateur(s) national(aux) pour l&#8217;AI Act si l&#8217;on veut être un tant soit peu en phase avec le reste de l&#8217;Europe. Pour obtenir des outils pratiques qui peuvent, entre autres, vous aider à vous mettre en conformité, vous pouvez d&#8217;ores et déjà consulter la base de données du <a href="https://data-en-maatschappij.ai/tags/ai-act">Kenniscentrum Data &amp; Maatschappij</a>. De nombreux autres documents y seront certainement publiés lorsque l&#8217;AI Act entrera effectivement en vigueur.</p>



<p>______________________</p>



<p><em><em>Cette contribution a été soumise par Joachim Ganseman, consultant IT chez Smals Research. Elle a été rédigée en son nom propre et ne prend pas position au nom de Smals.</em></em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Een eerste kennismaking met de AI Act</title>
		<link>https://www.smalsresearch.be/een-eerste-kennismaking-met-de-ai-act/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Mon, 15 Jul 2024 02:00:00 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[audit]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[sustainability]]></category>
		<guid isPermaLink="false">/?p=20654</guid>

					<description><![CDATA[Meer over de Europese AI Act, de laatste hoeksteen van een reeks grootschalige wetgevende initiatieven die de digitale economie in Europa in een gereguleerd framework moeten gieten.]]></description>
										<content:encoded><![CDATA[
<p><em>Cet article est aussi disponible <a href="/premier-tour-dhorizon-de-lai-act/">en français</a>.</em></p>



<p><em>Noot: dit is een populariserend artikel over toekomstige regelgeving, gebaseerd op de <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=OJ:L_202401689">officiële publicatie dd. 12/07/2024</a>. Wend u steeds tot een jurist voor professioneel juridisch advies. </em></p>



<p>De <a href="https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai">Europese AI Act</a> (in het Nederlands de <em>verordening artificiële intelligentie</em>) is een hoeksteen van een reeks grootschalige wetgevende initiatieven die de digitale economie in Europa in een gereguleerd framework moeten gieten. Ze is daarmee complementair met eerdere wetgeving die bepaalde aspecten van het AI-gebeuren beïnvloedt, zoals de <a href="https://eur-lex.europa.eu/eli/reg/2016/679/oj">GDPR (AVG)</a>, de <a href="https://digital-strategy.ec.europa.eu/en/policies/digital-services-act-package">Digital Services Act (DSA) en Digital Markets Act (DMA)</a>, de <a href="https://digital-strategy.ec.europa.eu/en/policies/data-act">Data Act</a>, de <a href="https://digital-strategy.ec.europa.eu/en/policies/data-governance-act">Data Governance Act</a>, de <a href="https://digital-strategy.ec.europa.eu/en/policies/european-chips-act">CHIPS Act</a> en de voorgestelde <a href="https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act">Cyber Resilience Act</a> . Na lang onderhandelen werd de AI Act in maart 2024 goedgekeurd door het Europees parlement en in mei door de Europese raad. De publicatie in het Official Journal of the European Union, zeg maar het Europese Staatsblad, vond plaats op <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=OJ:L_202401689">12 juli 2024</a>, waarna de eerste regels begin 2025 van kracht worden &#8211; zie ook <a href="https://artificialintelligenceact.eu/developments/">deze tijdslijn</a>.</p>



<h2 class="wp-block-heading">GDPR bis?</h2>



<p>De volledige (Engelstalige) tekst van de AI Act, inclusief alle voorbeschouwingen en bijlagen, is een fenomenale <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=OJ:L_202401689">144 bladzijden lang</a> &#8211; gelukkig zijn er <a href="https://www.stibbe.com/publications-and-insights/the-eu-artificial-intelligence-act-our-16-key-takeaways">her en der</a> al <a href="https://artificialintelligenceact.eu/high-level-summary/">goede samenvattingen</a> te vinden. Daarmee is ze bijna 2 keer langer dan de &#8220;slechts&#8221; <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32016R0679">88 pagina&#8217;s tellende GDPR</a>. Van die laatste is de impact enorm: elke organisatie die persoonsgegevens verwerkt &#8211; een personeelsadministratie of klantenbestand hebben is voldoende &#8211; kreeg te maken met DPO&#8217;s, verwerkingsregisters, en rechtsgronden voor gegevensverwerking. Elk land moest ook een <a href="https://www.gegevensbeschermingsautoriteit.be/">Gegevensbeschermingsautoriteit</a> opzetten met de bevoegdheid om <a href="https://www.dailybits.be/item/overzicht-gdpr-boetes-rechtszaken/#BE">inbreuken te beboeten</a>.</p>



<p>De GDPR bracht ook heel wat onzekerheid met zich mee, met name door haar veelvuldig gebruik van termen die voor interpretatie vatbaar zijn (&#8220;appropriate&#8221;, &#8220;adequate&#8221;, &#8220;suitable&#8221;, &#8220;sufficient&#8221;, &#8230;). De nood om die opnieuw te concretiseren voor elke voorliggende zaak, is de voedingsbodem voor wat ondertussen een kleine juridische industrie kan genoemd worden. De AI Act poogt om iets meer houvast te geven, door een meer technische toer op te gaan. Zo bevat ze een lijst Annexen met praktische opsommingen over wat verwacht wordt als gevraagd wordt naar documentatie, conformiteit, transparantie e.d.</p>



<p>De AI Act begon met een compacter voorstel van <a href="https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:52021PC0206">125 bladzijden (inclusief bijlagen)</a>. Tijdens de onderhandelingen zagen we echter de razendsnelle opkomst van generatieve AI en de Large Language Models. Dat noodzaakte om een en ander te herzien en toe te voegen, zoals een nieuw hoofdstuk (5) over <em>General Purpose AI</em>, waartoe LLMs gerekend kunnen worden. Van andere onderdelen kan men zich dan weer afvragen wat ze in de AI Act komen doen, zoals een systeem van &#8220;Regulatory Sandboxes&#8221; (Art.57) dat regulatoren moet toelaten om innovatie te faciliteren. Sommige artikels zijn wel erg cryptisch verwoord, zoals de sectie over &#8220;Notified Conformity Assessment Bodies&#8221; (Art.29), waarmee men eigenlijk <a href="https://www.hiig.de/en/eu-ai-act/">gewoon auditors bedoelt</a>. Er zijn dan ook <a href="https://www.euractiv.com/section/digital/news/the-long-and-winding-road-to-implement-the-ai-act/">kritische stemmen</a> te horen, die vrezen dat de resulterende optelsom aan maatregelen vooral een ingewikkeld kluwen is geworden.</p>



<h2 class="wp-block-heading">De AI Act &#8211; basics</h2>



<p>De AI Act is gericht op AI-ontwikkelaars en -aanbieders, en dat eigenlijk pas zodra ze AI-systemen publiceren en ter beschikking stellen van derden. Alle in-house ontwikkeling en testing die daaraan vooraf gaat, is expliciet uitgezonderd (Art.2§8). De AI Act grijpt ook niet in op wat je persoonlijk in niet-professionele context doet (Art.2§10). Wetenschappelijk onderzoek (Art.2§6) en militaire toepassingen (Art.2§3) tellen ook niet mee. Dat betekent natuurlijk niet dat in al die gevallen alles mag: uiteraard blijft andere bestaande wetgeving gewoon van kracht. De rechten van burgers werden al beschermd door de <a href="https://gdpr-info.eu/art-22-gdpr/">GDPR met o.a. haar Art.22</a>, en de auteursrechtenwetgeving blijft auteurs beschermen.</p>



<p>De gehanteerde definitie van AI is dan weer opvallend breed, en is geleend van de <a href="https://oecd.ai/en/wonk/ai-system-definition-update">OESO</a>: samengevat, &#8220;AI systems infer, from their input, how to generate outputs&#8221; (Art.3 + Overweging 12). Zowat alle machine learning valt daaronder. In andere definities leest men al eens dat er een cognitief aspect aan AI verbonden is (er moet iets &#8220;herkend&#8221; worden), maar daar is hier geen sprake van. Ook over specifieke technieken wordt met geen woord gerept: al wat adaptief leert of enigszins autonoom kan reageren op de omgeving, valt er haast altijd onder. Dit gaat dus ook over systemen die je al jarenlang kent, zonder er bij stil te staan dat er AI achter zit: spamfilters, aanbevelingen op websites, zelfs weersvoorspellingen.</p>



<p>De AI Act definieert eerst en vooral een lijst met verboden toepassingen (Art.5), die begin 2025 al van kracht zal worden. Deze lijst is een limitatieve opsomming, wat in principe ook betekent dat wat niet expliciet verboden is, toegelaten is (tenzij verhinderd door andere wetten). Het is daarom interessant om in detail te kijken wat wel en niet in die lijst staat, en met welke bijkomende bepalingen. Zo lezen we:</p>



<ul class="wp-block-list">
<li>§1(f): Het verbod op emotieherkenning vermeldt enkel de werkvloer en het onderwijs,</li>



<li>§1(g): Het verbod op biometrische AI-systemen vermeldt enkel de automatische afleiding van ras, seksualiteit, vakbondslidmaatschap, religie, politieke en filosofische overtuiging, </li>



<li>§1(e): Het verbod op gezichtsherkenning heeft het enkel over systemen op basis van &#8220;untargeted scraping&#8221;, </li>
</ul>



<p>Het is genuanceerder dan een lijstje algemene verbodsbepalingen, want ook context en doel spelen een rol. Emotieherkenning in bijvoorbeeld computergames blijft op die manier dus toegelaten. Overwegingen 15-17 preciseren dat biometrische AI toegelaten blijft voor identiteitsverificatie en authenticatie. Daarnaast zijn er ook enkele uitzonderingen ingebouwd voor o.a. de medische hulpverlening en de criminaliteitsbestrijding &#8211; al worden die uitzonderingen wel onder een streng toezicht geplaatst (Art.5§2-§7), inclusief een lijst van criminaliteit die ervoor in aanmerking komt (Annex 2).</p>



<p>Systemen die instaan voor de veiligheid van gebruikers, of die opgesomd zijn in Annex 3, zijn hoogrisico-systemen (Art.6). Het gaat hierbij vooral om systemen die een grote impact kunnen hebben op iemands vrijheden, levensloop, carrière of gezondheid. Hoewel dit onderdeel van de AI Act pas in voege zal treden in de zomer van 2026, valt het op dat er nog verschillende gaten in te vullen zijn. Zo moet de Commissie nog met een reeks verduidelijkende richtlijnen komen voor de interpretatie van dit artikel (Art.6§5), en behoudt ze zich het recht voor om ook achteraf nog wijzigingen aan te brengen (Art.6§6-§8, Art.7).</p>



<h2 class="wp-block-heading">AI Act &#8211; verplichtingen </h2>



<p>Wie een hoogrisicosysteem wil bouwen of gebouwd heeft, zal aan een reeks verplichtingen moeten voldoen, die o.a. moeten toelaten dat de bevoegde autoriteiten kunnen ingrijpen als het ontspoort. Ontwikkelaars van hoogrisicosystemen zullen bepaalde praktijken moeten adopteren, waaronder:</p>



<ul class="wp-block-list">
<li>Een iteratief risicobeheerssysteem (Art.9), dat moet toelaten de risico&#8217;s te inventariseren, in te schatten, en potentieel misbruik op voorhand te mitigeren. Concreter dan dat wordt het niet gemaakt: de tekst spreekt van &#8220;reasonably foreseeable risks&#8221; en &#8220;appropriate measures&#8221; zonder verdere specificatie. Dit zal dus nog voor wat discussie zorgen, maar in de praktijk kan men zich vandaag al deels behelpen met standaarden die recent voor dit doel ontwikkeld zijn, zoals <a href="https://www.iso.org/standard/81230.html">ISO/IEC 42001</a> &#8211; met dien verstande dat die niet expliciet voor de AI Act is gemaakt en bijkomende maatregelen nodig kunnen zijn.</li>



<li>Kwalitatief databeheer (Art.10), wat er grotendeels op neerkomt dat er transparantie moet zijn over de oorsprong, beperkingen, foutenmarges en representativiteit. Het gebruik van &#8220;<a href="https://arxiv.org/abs/1803.09010">Data Sheets</a>&#8220;, die dit beogen, was de laatste jaren in de sector sowieso al populair geworden.</li>



<li>Het voorzien van technische documentatie volgens de vereisten in Annex 4 (Annex 11 voor General Purpose AI). Dit is enigszins analoog met de <a href="https://huggingface.co/docs/hub/model-cards">Model Cards</a> zoals men die kan vinden op de HuggingFace Hub, al neemt de Europese Commissie geen genoegen met afgevinkte lijstjes en vraagt ze meer detail, onder andere over monitoring en controle tijdens de levensduur van het systeem.</li>



<li>Het voorzien van logging (Art.12) en transparante informatievoorziening naar de gebruikers toe (Art.13)</li>



<li>Menselijk overzicht tijdens de levensduur van het systeem (Art.14). Waar GDPR art.22 daar al een burgerrecht van maakte, verplicht de AI Act aan de ontwikkelaars om de nodige maatregelen daartoe te nemen. Er zal bijvoorbeeld altijd de mogelijkheid moeten zijn om het AI-systeem te negeren, te overrulen, of te stoppen (Art.14§4(d-e)).</li>



<li>Het nemen van &#8220;appropriate&#8221; maatregelen inzake cybersecurity, robuustheid en accuraatheid (Art.15). Ook dit artikel blijft momenteel nog relatief vaag en verwijst naar de intentie van de Commissie om de ontwikkeling van de nodige benchmarks te ondersteunen. </li>
</ul>



<p>Wie een hoogrisicosysteem publiceert, ter beschikking stelt, verwerkt in een eigen product, importeert of distribueert, zal gelijkaardige maatregelen moeten nemen, waaronder: </p>



<ul class="wp-block-list">
<li>De conformiteit van het systeem controleren en bewijzen (Art.16§e-l, Art. 40-47), een conformiteitsverklaring opstellen (Annex 5), en CE markering bekomen (Art.48)</li>



<li>Een kwaliteitsmanagementsysteem benutten (Art.17)</li>



<li>De nodige documentatie tot 10 jaar na ingebruikname bijhouden (Art.18)</li>



<li>Samenwerken met de bevoegde autoriteiten (Art.21) </li>



<li>Het systeem registreren (Art.49) in een speciaal daartoe opgezette EU database (Art.71)</li>



<li>Voor al het bovenstaande een contactpersoon of vertegenwoordiger aanduiden (Art.22)</li>



<li>De nodige monitoring opzetten en actie ondernemen wanneer het misloopt (Art.26§5, Art.72-73), waaronder het inlichten van de bevoegde autoriteit.</li>
</ul>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg"><img loading="lazy" decoding="async" width="606" height="335" src="/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg" alt="" class="wp-image-20899" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759.jpg 606w, https://www.smalsresearch.be/wp-content/uploads/2024/07/ai_lifecycle_visual_7FC0D14E-A775-A92E-DE5A38FDB7C238EB_75759-300x166.jpg 300w" sizes="auto, (max-width: 606px) 100vw, 606px" /></a><figcaption class="wp-element-caption">Lifecycle voor hoog-risico AI systemen onder de AI Act. Image (c) European Union, CC-BY-4.0</figcaption></figure>



<p>Naar analogie met Gegevensbeschermingseffectbeoordeling (Data Protection Impact Assessment &#8211; DPIA) uit de GDPR, zullen sommige organisaties, waaronder alle overheidsinstanties en organisaties van publieke dienstverlening, een <a href="https://www.technologyslegaledge.com/2024/03/fundamental-rights-impact-assessments-under-the-eu-ai-act-who-what-and-how/">Fundamental Rights Impact Assessment of FRIA</a> moeten uitvoeren, waarvan de resultaten aan de <a href="https://single-market-economy.ec.europa.eu/single-market/goods/building-blocks/market-surveillance/organisation_en">bevoegde marktregulatoren</a> meegedeeld moeten worden (Art. 27). Het Europese AI Office krijgt alvast de taak om voor deze verplichting de nodige geautomatiseerde vragenlijsten te ontwikkelen (Art. 27§5).</p>



<p>Men zou bijna vergeten dat verreweg de meeste AI-systemen gewoon laag-risico systemen zijn. Daarover is de AI Act vrij kort: die moet enkel voor specifieke toepassingen voldoen aan minimale transparantievereisten (Art.50). Zo moet de eindgebruiker altijd weten wanneer die met een AI-systeem interageert, en moet artificieel gegenereerde output duidelijk als dusdanig gemarkeerd worden. Met die gevreesde wurggreep rond de gehele AI-industrie valt het dus eigenlijk best wel mee.</p>



<h2 class="wp-block-heading">General purpose AI</h2>



<p>De recente ontwikkeling van algemeen inzetbare generatieve AI voor tekst en afbeeldingen noopte tot de toevoeging van een aparte categorie aan systemen: General Purpose AI (GPAI). De Europese Commissie is van mening dat dit soort AI, onafhankelijk van een eventueel hoog risico inzake burgerrechten, ook een systemisch risico met zich mee kan brengen (Art.51). Of dat gegrond is of niet, is in zowel technische als filosofische kringen onderwerp van <a href="https://quillette.com/2024/07/02/superintelligence-10-years-on-nick-bostrom-ai-safety-agi/">fel debat</a>, maar de EU neemt het zekere voor het onzekere en voorziet een juridische stok achter de deur.</p>



<p>De Commissie geeft zichzelf de vrijheid om te beslissen welke systemen zo&#8217;n risico manifesteren (Art.51§1). Hoewel ze zich voorneemt daarvoor objectieve criteria te benutten (Annex 13), is er geen vaste formule. Of toch: er is verrassend genoeg 1 opvallend concrete grenswaarde vastgelegd in Art.51§2: vanaf dat de training 10<sup>25</sup> FLOPs aan rekenkracht vergt, wordt een GPAI per definitie aanzien als systemisch risicovol. Dit komt ongeveer overeen met een trainingstijd van 1 jaar op een cluster van 4000 GPUs van het type Nvidia RTX4090 (met 82*10<sup>12</sup> FLOPs aan rekenkracht). Om te vermijden dat dit alles morgen al achterhaald is, behoudt de Commissie zich het recht voor om deze waarden in de toekomst aan te passen aan de evoluties in het domein (Art.51§3).</p>



<p>General Purpose AI wordt, naast de minimale vereisten van Art.50, en ongeacht de risicoclassificatie, onderworpen aan een eigen reeks technische documentatieverplichtingen (Art. 53, Annex 11), die nog wat uitgebreid worden wanneer een systemisch risico aanwezig is (Art. 55). Bouwers van GPAI modellen zonder systemisch risico die onder vrije (<sup data-fn="f4906311-978e-4fea-876e-d0742b6b3186" class="fn"><a href="#f4906311-978e-4fea-876e-d0742b6b3186" id="f4906311-978e-4fea-876e-d0742b6b3186-link">1</a></sup>) open-source licenties worden vrijgegeven, zijn van sommige verplichtingen uitgezonderd (Art.53§2, zie ook Overwegingen 102-104), en hoeven ook geen contactpersoon of vertegenwoordiger aan te duiden (Art.54§6).  </p>



<h2 class="wp-block-heading">Het AI Office</h2>



<p>De AI Act zal ook afgedwongen moeten worden. Een grote rol daarbij is weggelegd voor het <a href="https://digital-strategy.ec.europa.eu/en/policies/ai-office">Europese AI Office</a> (NL: <em>AI-bureau</em>, Art.64), dat voor de AI Act moet zijn wat de <a href="https://www.edps.europa.eu/">European Data Protection Supervisor</a> is voor de GDPR. Het AI Office wordt momenteel aan sneltempo in de steigers gezet, want begin 2025 treden de eerste bepalingen in voege. Naast de verantwoordelijkheid om nog een reeks openstaande onderdelen van de AI Act in te vullen, zal ze ook exclusief bevoegd worden voor het toezicht op General Purpose AI (Art.75).</p>



<p>Het AI Office wordt in de praktijk onderdeel van <a href="https://digital-strategy.ec.europa.eu/">DG CONNECT</a>, zal van start gaan met 140 medewerkers en geleid worden door <a href="https://www.euronews.com/next/2024/05/29/ai-office-set-up-announced-lucilla-sioli-to-be-in-charge">Lucilla Sioli</a>. Het zal voor haar werking ondersteund worden door het <a href="https://algorithmic-transparency.ec.europa.eu/">Centrum voor Algoritmische Transparantie (ECAT)</a>, een <a href="https://digital-strategy.ec.europa.eu/en/news/commission-hosts-high-level-meeting-upcoming-eus-ai-board-drive-ai-act-implementation-forward">AI Board</a> (Art.65), een adviserend forum van belanghebbenden (Art.67), en een panel van onafhankelijke wetenschappers (Art.68).</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg"><img loading="lazy" decoding="async" width="800" height="592" src="/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg" alt="" class="wp-image-20902" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002.jpg 800w, https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002-300x222.jpg 300w, https://www.smalsresearch.be/wp-content/uploads/2024/07/AI-NEW-OFFICE-organigramme-002-768x568.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></a><figcaption class="wp-element-caption">Organigram van het EU AI Office. Image (c) European Union, CC-BY-4.0</figcaption></figure>



<p>Ook nationaal moeten er regulatoren worden aangeduid (Art.70). Deze zullen nauw moeten samenwerken met het EU AI Office en met de reeds bestaande industriële en sectorale regulatoren, die bijvoorbeeld vandaag al voor CE-markeringen bevoegd zijn. <a href="https://www.autoriteitpersoonsgegevens.nl/actueel/ap-en-rdi-toezicht-op-ai-systemen-vraagt-samenwerking-en-moet-snel-geregeld-worden">In Nederland speelt de Autoriteit Persoonsgegevens een duidelijke voortrekkersrol</a> in de uitwerking van een Nederlandse AI-autoriteit, die daar waarschijnlijk in de schoot van de Autoriteit Persoonsgegevens zal worden opgericht. In België blijft het ondertussen <a href="https://data-en-maatschappij.ai/nieuws/gastblog-waar-blijft-de-belgische-toezichthouder-voor-algoritmes">stil</a>, hoewel de tijd dringt &#8211; je kan immers ook niet eender wie aanwerven om die vrij gespecialiseerde rollen in te vullen.</p>



<h2 class="wp-block-heading">Conclusie</h2>



<p>Het is belangrijk om te onthouden dat de AI Act geen beperkingen oplegt aan AI-systemen die weinig risico inhouden &#8211; met uitzondering van General Purpose AI waarvan de nodige transparantie wordt gevraagd. Alleen voor systemen die hoge of systemische risico&#8217;s met zich meebrengen en in productie worden gezet, komen er strikte vereisten en de noodzaak tot conformiteit met relevante reguleringen. Ook dan zijn er heel wat verzachtende maatregelen die de interne ontwikkeling, open source initiatieven, wetenschap, defensie enz. extra ademruimte geven.</p>



<p>Tot op zekere hoogte probeert de AI Act concreet te zijn, door in detail op te sommen wat er verwacht wordt en een resem verduidelijkingen in de Overwegingen en Annexen op te nemen. Ze slaagt daar deels in en wordt zo nogal technisch &#8211; een betrokken rechter zal moeten leren wat FLOPs zijn. Tegelijk zijn er nog heel wat gaten in te vullen, waarbij het afwachten wordt waar het nieuwe AI Office onder toekomstige Commissies de lat zal leggen. Op verschillende plekken werd de mogelijkheid voorzien om de AI Act later te amenderen. De huidige versie van de AI Act zal dus zeker niet de laatste zijn.</p>



<p>Tenslotte mogen we in België zeker niet te lang meer wachten met het aanduiden en organiseren van de nationale toezichthouder(s) voor de AI Act, als we enigszins mee willen zijn met de rest van Europa. Voor praktische tools die o.a. kunnen helpen om conform te zijn, kan je vandaag al zoeken in de database van het <a href="https://data-en-maatschappij.ai/tags/ai-act">Kenniscentrum Data &amp; Maatschappij</a>. Daar zal zeker nog veel meer materiaal verschijnen eens de AI Act effectief in werking treedt.</p>



<p>______________________</p>



<p><em>Dit is een ingezonden bijdrage van Joachim Ganseman, IT consultant bij Smals Research. &nbsp;Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>


<ol class="wp-block-footnotes"><li id="f4906311-978e-4fea-876e-d0742b6b3186"> In de ontwerptekst was het Engelse &#8220;free&#8221; <a href="https://tweakers.net/reviews/12020/hoe-de-eu-ai-hoopt-te-reguleren-ict-jurist-engelfriet-over-de-ai-act.html">oorspronkelijk foutief vertaald als &#8220;gratis&#8221;</a>. In de publicatie in het Official Journal is deze vertaalfout alsnog gecorrigeerd en staat er &#8220;vrij&#8221;. <a href="#f4906311-978e-4fea-876e-d0742b6b3186-link" aria-label="Jump to footnote reference 1"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></li></ol>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Les assistants de codage open source à l&#8217;ouvrage </title>
		<link>https://www.smalsresearch.be/opensource-coding-assistants-fr/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Thu, 28 Mar 2024 09:37:20 +0000</pubDate>
				<category><![CDATA[[FR]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[computational creativity]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">/?p=20319</guid>

					<description><![CDATA[Un assistant de codage respectueux de la vie privée pour un IDE avec des outils open source - comment faire ? ]]></description>
										<content:encoded><![CDATA[
<p><em>Cet article est aussi disponible <a href="/opensource-coding-assistants/">en néerlandais</a>.</em></p>



<p>Comme outil de génération de code pour les développeurs de logiciels, <a href="https://github.com/features/copilot" target="_blank" rel="noreferrer noopener">Github Copilot</a> domine le marché aujourd&#8217;hui. Cette situation devrait perdurer, d&#8217;autant plus que l&#8217;outil s&#8217;est enrichi d&#8217;une fonctionnalité de messagerie instantanée à la ChatGPT. Propriété de Microsoft, Github bénéficie d&#8217;une ligne directe avec OpenAI, et est donc le premier à profiter du rôle de pionnier que cette société continue de jouer dans le développement de <a href="https://fr.wikipedia.org/wiki/Grand_mod%C3%A8le_de_langage">grands modèles de langage</a> (abrégé <a href="https://en.wikipedia.org/wiki/Large_language_model" target="_blank" rel="noreferrer noopener">LLM en anglais)</a>&nbsp;</p>



<p>On en oublierait presque qu&#8217;il existe d&#8217;autres options. La première alternative à grande échelle construite sur une base open source, incluant des <a href="https://huggingface.co/datasets/bigcode/the-stack">jeux de données d&#8217;apprentissage ouverts</a>, est <a href="https://huggingface.co/blog/starcoder" target="_blank" rel="noreferrer noopener">StarCoder</a>, dont une <a href="https://github.com/bigcode-project/starcoder2" target="_blank" rel="noreferrer noopener">version 2</a> a récemment vu le jour. Elle est développée dans le cadre de l&#8217;<a href="https://www.bigcode-project.org/" target="_blank" rel="noreferrer noopener">initiative BigCode</a> de ServiceNow et de HuggingFace. L&#8217;<a href="https://arxiv.org/abs/2305.06161" target="_blank" rel="noreferrer noopener">article qui l&#8217;accompagne</a> offre un aperçu fascinant de la construction d&#8217;un modèle de langage pour la génération de code. Peu après StarCoder, <a href="https://arxiv.org/abs/2306.08568" target="_blank" rel="noreferrer noopener">WizardCoder</a>, <a href="https://arxiv.org/abs/2308.12950" target="_blank" rel="noreferrer noopener">CodeLLama</a>, <a href="https://github.com/deepseek-ai/DeepSeek-Coder" target="_blank" rel="noreferrer noopener">DeepSeekCoder</a> et quelques autres sont apparus sur la scène, pas tous fondés sur un ensemble de données ouvertes, mais librement accessibles et réutilisables via <a href="https://huggingface.co/" target="_blank" rel="noreferrer noopener">HuggingFace</a>. &nbsp;</p>



<p>Aujourd’hui, il existe aussi suffisamment d&#8217;outils pour faciliter l&#8217;exécution de ces modèles sur votre propre machine. Vous pouvez donc avoir votre propre assistant de codage personnel, hébergé par vous-même et entièrement privé. Pour cela, il vous faut un matériel suffisamment puissant, un LLM axé sur les tâches de <em>code completion</em> ou sur les conversations concernant le code, et une extension pour l&#8217;environnement de développement (IDE). Le LLM et l’extension de l’IDE communiquent entre eux via une API, qui peut être compatible ou non avec celle d&#8217;OpenAI, ce qui permet de passer facilement d&#8217;un modèle commercial (OpenAI) à un modèle open source le cas échéant.&nbsp;</p>



<h2 class="wp-block-heading"><strong>Extensions pour IDE</strong></h2>



<p>L&#8217;installation d&#8217;une extension est simple en soi. Github Copilot existe depuis longtemps en tant qu&#8217;<a href="https://code.visualstudio.com/docs/editor/github-copilot" target="_blank" rel="noreferrer noopener">extension pour VSCode</a> et aujourd&#8217;hui également pour <a href="https://plugins.jetbrains.com/plugin/17718-github-copilot" target="_blank" rel="noreferrer noopener">IntelliJ IDEA</a> &#8211; même si au moment de la rédaction de cet article, la version d’IntelliJ contient encore un peu moins de fonctionnalités.&nbsp;&nbsp;</p>



<p>Parmi les alternatives open source, <a href="https://continue.dev/" target="_blank" rel="noreferrer noopener">Continue</a> figure probablement parmi les meilleures à ce jour. Il en existe d&#8217;autres &#8211; Huggingface a développé <a href="https://github.com/huggingface/llm-vscode?tab=readme-ov-file" target="_blank" rel="noreferrer noopener">llm-vscode</a> par exemple &#8211; et il ne fait aucun doute que d&#8217;autres viendront s&#8217;ajouter. Tout comme Github Copilot, Continue existe également sous forme d&#8217;<a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" target="_blank" rel="noreferrer noopener">extension pour VSCode</a> ou <a href="https://plugins.jetbrains.com/plugin/22707-continue" target="_blank" rel="noreferrer noopener">IntelliJ</a>. L&#8217;outil peut utiliser à la fois des générateurs commerciaux basés sur le cloud (notamment GPT-4) et des solutions open source auto-hébergées, qui ne doivent pas nécessairement émuler l&#8217;API d&#8217;OpenAI et autorisent de nombreuses personnalisations.&nbsp;</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/03/2024-03-11_14h59_32.png"><img loading="lazy" decoding="async" width="1024" height="410" src="/wp-content/uploads/2024/03/2024-03-11_14h59_32-1024x410.png" alt="" class="wp-image-20216" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-1024x410.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-300x120.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-768x308.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-1536x615.png 1536w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32.png 1858w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Capture d’écran de l&#8217;extension Continue dans Visual Studio Code&nbsp;</figcaption></figure>



<p>Il demeure important de prendre le temps de se familiariser avec l’extension. La <a href="https://continue.dev/docs/intro" target="_blank" rel="noreferrer noopener">documentation de Continue</a> constitue une bonne base à cet effet. Pour chaque <a href="https://continue.dev/docs/model-setup/select-provider" target="_blank" rel="noreferrer noopener">serveur</a> et chaque <a href="https://continue.dev/docs/model-setup/select-model" target="_blank" rel="noreferrer noopener">LLM</a>, il se peut que vous deviez définir différentes options de configuration et que vous souhaitiez apporter des modifications à <a href="https://continue.dev/docs/model-setup/configuration" target="_blank" rel="noreferrer noopener">l&#8217;invite de commande</a> sous-jacente. Il convient également de savoir comment activer et désactiver l&#8217;extension dans l&#8217;IDE et de connaître les raccourcis et <a href="https://continue.dev/docs/customization/slash-commands" target="_blank" rel="noreferrer noopener">commandes</a> disponibles. <a href="https://www.youtube.com/results?search_query=continue+ai" target="_blank" rel="noreferrer noopener">YouTube</a> peut être un bon point de départ pour trouver des tutoriels et des exemples d&#8217;autres utilisateurs.&nbsp;</p>



<h2 class="wp-block-heading"><strong>Un LLM sur votre ordinateur portable</strong>&nbsp;</h2>



<p>Notamment sous l&#8217;impulsion du projet open source <a href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noreferrer noopener">llama.cpp</a>, des efforts considérables ont été faits au cours de l&#8217;année écoulée pour faire en sorte que les LLM puissent également être déployés sur du matériel informatique grand public. Un processeur graphique (GPU) au coût prohibitif n&#8217;est plus nécessaire, même s&#8217;il offre un gain de temps considérable. Globalement, <a href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noreferrer noopener">llama.cpp</a> permet de reconditionner un modèle au format GGUF (GPT-Generated Unified Format). Il s&#8217;agit ici d&#8217;appliquer un maximum d&#8217;optimisations :&nbsp;</p>



<p></p>



<ul class="wp-block-list">
<li>l&#8217;utilisation de jeux d&#8217;instructions du processeur (<s> </s>CPU) efficaces tels que&nbsp; <a href="https://en.wikipedia.org/wiki/AVX-512" target="_blank" rel="noreferrer noopener">AVX-512</a> &#8211; il va sans dire que le matériel sur lequel le modèle fonctionnera plus tard doit également prendre en charge ces jeux d&#8217;instructions ;&nbsp;</li>



<li>l&#8217;utilisation de bibliothèques hautement optimisées pour les calculs sous-jacents, telles que <a href="https://github.com/OpenMathLib/OpenBLAS" target="_blank" rel="noreferrer noopener">openBLAS</a> ou <a href="https://developer.apple.com/documentation/accelerate" target="_blank" rel="noreferrer noopener">Accelerate</a> et <a href="https://developer.apple.com/metal/" target="_blank" rel="noreferrer noopener">Metal</a> d&#8217;Apple ;&nbsp;</li>



<li>la <em>quantification </em>du modèle, par la réduction de la <a href="https://en.wikipedia.org/wiki/Precision_(computer_science)" target="_blank" rel="noreferrer noopener">précision</a> des poids dans les couches des réseaux neuronaux. Les nombres (à virgule flottante) de 16 ou 32 bits du modèle original sont ici convertis en nombres entiers de 8 bits, voire de 6 bits ou même de 4 bits. Cela permet d&#8217;économiser de la mémoire et d&#8217;accélérer les calculs, au prix d&#8217;une perte de qualité relativement faible.&nbsp;</li>
</ul>



<p>L&#8217;hébergement local d&#8217;un LLM peut être réalisé à l&#8217;aide d&#8217;outils tels que <a href="https://lmstudio.ai/" target="_blank" rel="noreferrer noopener">LM Studio</a>. Ceux-ci vous permettent de télécharger différents modèles au format GGUF. Un onglet séparé dans l&#8217;application vous permet de démarrer un serveur d&#8217;inférence utilisant le protocole HTTP autour d&#8217;un modèle téléchargé et activé, qui simule l&#8217;API d&#8217;OpenAI. Une fois ce serveur mis en place, par exemple sur le port 1234, le modèle est accessible via un appel à <code>http://localhost:1234/v1/chat/completions</code> . </p>



<p>Cette configuration dans l&#8217;extension Continue se fait par l&#8217;ajout du LLM au fichier <code>.continue/config.json</code>, suivant <a href="https://docs.continue.dev/customize/overview" target="_blank" rel="noreferrer noopener">ces instructions</a> et selon les directives pour <a href="https://docs.continue.dev/customize/model-providers/more/lmstudio" target="_blank" rel="noreferrer noopener">LM Studio en tant que fournisseur de modèle</a>. Vous pouvez adapter le titre et le modèle comme bon vous semble, et il vous suffit d&#8217;ajouter la ligne <code>"apiBase":"http://127.0.0.1:1234/v1"</code> Dans l&#8217;extension, vous verrez alors apparaître une nouvelle option, et vous pourrez commencer à l&#8217;utiliser. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/03/2024-03-11_15h06_39.png"><img loading="lazy" decoding="async" width="1024" height="550" src="/wp-content/uploads/2024/03/2024-03-11_15h06_39-1024x550.png" alt="" class="wp-image-20217" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-1024x550.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-300x161.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-768x412.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-1536x825.png 1536w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39.png 1918w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">LM Studio, avec le modèle CodeNinja chargé, répond à une requête via le serveur intégré actif sur le port 1234.&nbsp;</figcaption></figure>



<h2 class="wp-block-heading"><strong>Interlude&nbsp;: à propos du matériel</strong></h2>



<p>La gestion des GPU n&#8217;est déjà pas une partie de plaisir pour un développeur sur une seule machine. Les problèmes d&#8217;incompatibilité entre les différentes versions de toutes sortes de bibliothèques logicielles et de pilotes de GPU peuvent prendre des jours à résoudre. L&#8217;<a href="https://www.nvidia.com/en-us/data-center/products/" target="_blank" rel="noreferrer noopener">offre du marché des GPUs pour data centers</a>, dominée par le monopole de nVIDIA, reste d&#8217;un coût prohibitif. À cela s&#8217;ajoute le coût de l&#8217;acquisition des connaissances très spécialisées nécessaires au fonctionnement de ces systèmes. Le matériel que vous choisirez sera probablement complètement obsolète dans quelques années. Un nouveau matériel, conçu spécifiquement pour accélérer le type de calculs des modèles d&#8217;IA, fait l&#8217;objet d&#8217;un travail acharné. Google a déjà présenté le <a href="https://en.wikipedia.org/wiki/Tensor_Processing_Unit" target="_blank" rel="noreferrer noopener">TPU</a>, mais d&#8217;autres fabricants se concentrent aujourd&#8217;hui pleinement sur les <a href="https://www.techradar.com/computing/cpu/what-is-an-npu" target="_blank" rel="noreferrer noopener">NPU (Neural Processing Units)</a>, et certains osent entrer en <a href="https://www.cerebras.net/" target="_blank" rel="noreferrer noopener">concurrence directe</a> avec nVIDIA.&nbsp;&nbsp;</p>



<p>Si vous n&#8217;avez pas le temps de vous occuper des pilotes de GPU et que vous n&#8217;avez pas l&#8217;ambition d&#8217;entraîner les modèles vous-même, la possibilité de les utiliser sur un CPU ordinaire est plus que bienvenue. Bien sûr, vous êtes alors limité aux LLM ou aux modèles d&#8217;IA dont la taille le permet. Les LLM &#8220;domestiques&#8221; typiques ont 3, 7 ou 13 milliards de paramètres ; les modèles plus grands sont <a href="https://github.com/ggerganov/llama.cpp#memorydisk-requirements" target="_blank" rel="noreferrer noopener">agressivement quantifiés</a> pour économiser de l&#8217;espace sur le disque et la mémoire.&nbsp; Ils ne seront pas en mesure d&#8217;égaler la qualité de GPT-4 aujourd&#8217;hui, mais heureusement, des classements existent pour aider à opérer un choix &#8211; pour <a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard" target="_blank" rel="noreferrer noopener">les LLM ouverts en général</a>, spécifiquement avec <a href="https://huggingface.co/spaces/optimum/llm-perf-leaderboard" target="_blank" rel="noreferrer noopener">des benchmarks de vitesse (débit)</a>, ou pour <a href="https://huggingface.co/spaces/bigcode/bigcode-models-leaderboard" target="_blank" rel="noreferrer noopener">les LLM générateurs de code</a> en particulier.&nbsp;</p>



<p>Plus les LLM sont grands, plus la qualité du résultat est élevée (en général), mais plus la mémoire et la puissance de traitement requises sont importantes. Un LLM doit de préférence pouvoir être entièrement chargé dans la mémoire, de sorte que 16 GB de RAM n&#8217;est pas un luxe &#8211; plus c&#8217;est encore mieux, surtout si vous voulez faire fonctionner un IDE sur la même machine. Pour fournir une réponse, le modèle complet doit souvent être exécuté plusieurs fois. Par conséquent, le goulot d&#8217;étranglement est souvent la bande passante entre le CPU et la RAM. Les CPU dotés d&#8217;une grande mémoire cache interne semblent avoir une longueur d&#8217;avance (voir également les benchmarks spécifiques à l&#8217;IA [<a href="https://www.anandtech.com/show/21084/intel-core-i9-14900k-core-i7-14700k-and-core-i5-14600k-review-raptor-lake-refreshed/10" target="_blank" rel="noreferrer noopener">1</a>,<a href="https://www.anandtech.com/show/21242/amd-ryzen-7-8700g-and-ryzen-5-8600g-review/8" target="_blank" rel="noreferrer noopener">2</a>] d&#8217;Anandtech). Lors du choix du reste du matériel, la bande passante de la mémoire devrait certainement entrer en ligne de compte. Même ceux choisissant un GPU pourraient préférer considérer cette bande passante plutôt que le nombre de cœurs du GPU. Enfin, dans les environnements virtualisés (VM, VPS), il est important que le CPU virtuel prenne en charge les mêmes jeux d&#8217;instructions avancés, tels que <a href="https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512" target="_blank" rel="noreferrer noopener">AVX-512</a>.&nbsp;</p>



<h2 class="wp-block-heading"><strong>Un LLM sur votre serveur</strong>&nbsp;</h2>



<p>Si vous disposez d&#8217;une machine plus puissante, il peut être intéressant d&#8217;y exécuter le LLM. <a href="https://ollama.com/" target="_blank" rel="noreferrer noopener">ollama</a> est probablement l&#8217;outil le plus populaire pour héberger des modèles sur Mac ou Linux sans trop de difficultés, et depuis peu également sur Windows. <a href="https://localai.io/" target="_blank" rel="noreferrer noopener">LocalAI</a> est toutefois une option tout aussi intéressante dans la liste des <a href="https://continue.dev/docs/model-setup/select-provider" target="_blank" rel="noreferrer noopener">fournisseurs de LLM pour Continue</a>, car il propose des conteneurs Docker, avec ou sans support GPU. Sur une machine Linux équipée de Docker, un <a href="https://localai.io/basics/getting_started/" target="_blank" rel="noreferrer noopener">one-liner</a> dans le terminal suffit pour télécharger le modèle CodeLlama open source et l&#8217;héberger sur le port 1234 :&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="docker run -ti -p 1234:8080 localai/localai:v2.7.0-ffmpeg-core codellama-7b-gguf " style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">docker</span><span style="color: #000000"> </span><span style="color: #A31515">run</span><span style="color: #000000"> </span><span style="color: #0000FF">-ti</span><span style="color: #000000"> </span><span style="color: #0000FF">-p</span><span style="color: #000000"> </span><span style="color: #098658">1234</span><span style="color: #A31515">:8080</span><span style="color: #000000"> </span><span style="color: #A31515">localai/localai:v2.7.0-ffmpeg-core</span><span style="color: #000000"> </span><span style="color: #A31515">codellama-7b-gguf</span><span style="color: #000000"> </span></span></code></pre></div>



<p></p>



<p>Cependant, son démarrage prend un certain temps, car le modèle est téléchargé dans le conteneur. Il est plus intéressant de stocker soi-même une série de modèles dans un répertoire local et d&#8217;y associer une API à l&#8217;aide d&#8217;un conteneur LocalAI. Des <a href="https://localai.io/docs/getting-started/models/" target="_blank" rel="noreferrer noopener">instructions</a> relativement simples sont disponibles pour cela aussi. Nous pouvons par exemple les appliquer au LLM <a href="https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF" target="_blank" rel="noreferrer noopener">LLM DeepSeek de 6,7 milliards de paramètres, quantifiés à 4 bits</a>. Il peut être téléchargé directement depuis Huggingface dans le répertoire local ./models-gguf à l&#8217;aide d&#8217;une commande wget du type : </p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="wget https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF/resolve/main/deepseek-coder-6.7b-instruct.Q4_K_M.gguf -O ./models-gguf/deepseek-6.7b-instruct-Q4" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">wget</span><span style="color: #000000"> </span><span style="color: #A31515">https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF/resolve/main/deepseek-coder-6.7b-instruct.Q4_K_M.gguf</span><span style="color: #000000"> </span><span style="color: #0000FF">-O</span><span style="color: #000000"> </span><span style="color: #A31515">./models-gguf/deepseek-6.7b-instruct-Q4</span></span></code></pre></div>



<p></p>



<p>Démarrer une API autour des modèles de ce répertoire sur le port 8001 (vous pouvez aussi placer plusieurs modèles dans le même répertoire et les héberger simultanément), peut alors se faire avec la commande suivante . Ajoutez éventuellement <em><code>-d</code></em> pour qu&#8217;elle s&#8217;exécute en arrière-plan, et n&#8217;hésitez pas à expérimenter les paramètres <em><code>context-size</code></em> et <em><code>threads</code> </em>en fonction de la puissance de votre serveur&nbsp;: </p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="docker run -p 8001:8080 -v $PWD/models-gguf:/models -ti --rm quay.io/go-skynet/local-ai:v2.7.0-ffmpeg-core --models-path /models --context-size 1600 --threads 16" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">docker</span><span style="color: #000000"> </span><span style="color: #A31515">run</span><span style="color: #000000"> </span><span style="color: #0000FF">-p</span><span style="color: #000000"> </span><span style="color: #098658">8001</span><span style="color: #A31515">:8080</span><span style="color: #000000"> </span><span style="color: #0000FF">-v</span><span style="color: #000000"> </span><span style="color: #001080">$PWD</span><span style="color: #A31515">/models-gguf:/models</span><span style="color: #000000"> </span><span style="color: #0000FF">-ti</span><span style="color: #000000"> </span><span style="color: #0000FF">--rm</span><span style="color: #000000"> </span><span style="color: #A31515">quay.io/go-skynet/local-ai:v2.7.0-ffmpeg-core</span><span style="color: #000000"> </span><span style="color: #0000FF">--models-path</span><span style="color: #000000"> </span><span style="color: #A31515">/models</span><span style="color: #000000"> </span><span style="color: #0000FF">--context-size</span><span style="color: #000000"> </span><span style="color: #098658">1600</span><span style="color: #000000"> </span><span style="color: #0000FF">--threads</span><span style="color: #000000"> </span><span style="color: #098658">16</span></span></code></pre></div>



<p></p>



<h2 class="wp-block-heading">Exemple</h2>



<p>Nous pouvons maintenant comparer différents LLM pour le code. Nous nous en tiendrons ici à l&#8217;anecdote et prendrons l&#8217;écriture d&#8217;un script shell <em>bash</em> comme exemple simple. Nous partons du problème suivant&nbsp;: une routine de sauvegarde a effectué des sauvegardes nocturnes d&#8217;un système pendant des années. Pour libérer de l&#8217;espace disque, nous voulons supprimer toutes les sauvegardes qui ne diffèrent pas des précédentes. Nous lançons la commande suivante, en décrivant la tâche le plus précisément possible afin d’obtenir les meilleurs résultats&nbsp;: <em>&#8220;Write a bash script that, given a directory, iterates over all its files in order of date of creation. For each file, if the filesize is equal to the filesize of the previous file, the file has to be deleted.&#8221;</em>&nbsp;</p>



<p></p>



<p></p>



<p>Le fichier <code>.continue/config.json</code> de notre extension Continue contient la liste suivante de modèles : un sur le propre ordinateur portable dans LM Studio chargé sur le port 1234, et deux sur un serveur séparé, mais sur le même réseau local, hébergé par LocalAI sur le port 8001.&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="    {
      &quot;title&quot;: &quot;myLaptop-LMStudio&quot;,
      &quot;model&quot;: &quot;whatever is loaded in LMstudio&quot;,
      &quot;apiBase&quot;: &quot;http://127.0.0.1:1234/v1&quot;,
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;lmstudio&quot;
    },       
    {
      &quot;title&quot;: &quot;localAI-mistral&quot;,
      &quot;model&quot;: &quot;mistral-7b-code16kqlora-Q4&quot;,
      &quot;apiBase&quot;: &quot;https://192.168.0.100:8001/v1&quot;,
      &quot;apiKey&quot;: &quot;&quot;,      
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;openai&quot;
    },
    {
      &quot;title&quot;: &quot;localAI-deepseek&quot;,
      &quot;model&quot;: &quot;deepseek-6.7b-instruct-Q4&quot;,
      &quot;apiBase&quot;: &quot;https://192.168.0.100:8001/v1&quot;,
      &quot;apiKey&quot;: &quot;&quot;,
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;openai&quot;
    }," style="color:#24292e;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki github-light" style="background-color: #fff" tabindex="0"><code><span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;myLaptop-LMStudio&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;whatever is loaded in LMstudio&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;http://127.0.0.1:1234/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;lmstudio&quot;</span></span>
<span class="line"><span style="color: #24292E">    },       </span></span>
<span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;localAI-mistral&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;mistral-7b-code16kqlora-Q4&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;https://192.168.0.100:8001/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiKey&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;&quot;</span><span style="color: #24292E">,      </span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;openai&quot;</span></span>
<span class="line"><span style="color: #24292E">    },</span></span>
<span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;localAI-deepseek&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;deepseek-6.7b-instruct-Q4&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;https://192.168.0.100:8001/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiKey&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;openai&quot;</span></span>
<span class="line"><span style="color: #24292E">    },</span></span></code></pre></div>



<p></p>



<p>Comme référence, nous prenons <a href="https://chat.openai.com/" target="_blank" rel="noreferrer noopener">ChatGPT</a>, qui propose la solution (correcte) suivante. &nbsp;<br>En outre, elle est également suivie d&#8217;une explication détaillée de la signification des différentes parties (non présentée ici) :&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

# Directory containing the files
DIR=&quot;/path/to/your/directory&quot;

# Variable to hold the size of the previous file. Initialized to 0.
prev_size=0

# List all files in the directory, sorted by creation date
# Note: '%T@' sorts by creation time, '%p' prints the file's name
# 'sort -n' ensures the list is sorted numerically
# Note that creation time sorting may depend on filesystem and OS support
files=$(find &quot;$DIR&quot; -type f -printf &quot;%T@ %p\n&quot; | sort -n | cut -d ' ' -f 2-)

# Iterate over the sorted list of files
for file in $files; do
  # Get current file size
  current_size=$(stat -c %s &quot;$file&quot;)
  
  # Check if current file size is equal to the previous file's size
  if [ &quot;$current_size&quot; -eq &quot;$prev_size&quot; ]; then
    # Sizes are equal, delete the current file
    echo &quot;Deleting file: $file&quot;
    rm &quot;$file&quot;
  fi
  
  # Update previous size to current file's size
  prev_size=$current_size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Directory containing the files</span></span>
<span class="line"><span style="color: #9CDCFE">DIR</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;/path/to/your/directory&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Variable to hold the size of the previous file. Initialized to 0.</span></span>
<span class="line"><span style="color: #9CDCFE">prev_size</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># List all files in the directory, sorted by creation date</span></span>
<span class="line"><span style="color: #6A9955"># Note: &#39;%T@&#39; sorts by creation time, &#39;%p&#39; prints the file&#39;s name</span></span>
<span class="line"><span style="color: #6A9955"># &#39;sort -n&#39; ensures the list is sorted numerically</span></span>
<span class="line"><span style="color: #6A9955"># Note that creation time sorting may depend on filesystem and OS support</span></span>
<span class="line"><span style="color: #9CDCFE">files</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">find</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$DIR</span><span style="color: #CE9178">&quot; </span><span style="color: #569CD6">-type</span><span style="color: #CE9178"> f </span><span style="color: #569CD6">-printf</span><span style="color: #CE9178"> &quot;%T@ %p\n&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">sort</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-n</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39; </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178">-)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Iterate over the sorted list of files</span></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$files</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Get current file size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">current_size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Check if current file size is equal to the previous file&#39;s size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$current_size</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> -eq </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$prev_size</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Sizes are equal, delete the current file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Deleting file: </span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Update previous size to current file&#39;s size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">prev_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$current_size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Dans LMStudio, nous chargeons le modèle &#8220;<a href="https://huggingface.co/TheBloke/CodeNinja-1.0-OpenChat-7B-GGUF" target="_blank" rel="noreferrer noopener">CodeNinja 1.0 openchat 7B Q4_K_M</a>&#8220;. Il faut plus d&#8217;une minute pour générer la réponse à la même question&nbsp;: 20 secondes d&#8217;attente pour l&#8217;apparition de la première lettre de la réponse, puis environ 2 secondes par ligne (bien sûr, notre ordinateur portable n&#8217;est pas très puissant&nbsp;: un CPU Core i7-10610U avec 32GB de RAM). Le résultat se présente comme suit :&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

for f in $(ls -t -l --time-style=full /path/to/directory)
do
  if [[ $f == &quot;total&quot;* ]]; then
        continue;
    fi
    filename=$(basename &quot;${f% *}&quot;)

    # Checks whether the file is already deleted. If not, compares it with the previous file:
    prev_file=&quot;&quot;
    while IFS= read -r line; do
        if [[ $line == $filename ]]; then
            prev_file=$line
            break;
        fi
    done &lt;&lt;&lt;&quot;$(ls -l /path/to/directory | tail -n 2)&quot;

    if [[ -z $prev_file || &quot;$f&quot; = &quot;${prev_file}&quot; ]]; then
        # If the file is deleted, nothing to do. If not, deletes it:
        if [[ -z $prev_file ]] || [[ &quot;$(stat -c %s ${filename})&quot; == &quot;$(stat -c %s ${prev_file})&quot; ]]; then
            rm /path/to/directory/$filename
        fi
    fi
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">f</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-t</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-l</span><span style="color: #CE9178"> </span><span style="color: #569CD6">--time-style=full</span><span style="color: #CE9178"> /path/to/directory)</span></span>
<span class="line"><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$f</span><span style="color: #D4D4D4"> == </span><span style="color: #CE9178">&quot;total&quot;</span><span style="color: #D4D4D4">* ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">continue</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">filename</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">basename</span><span style="color: #CE9178"> &quot;${</span><span style="color: #9CDCFE">f</span><span style="color: #D4D4D4">%</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">*</span><span style="color: #CE9178">}&quot;)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Checks whether the file is already deleted. If not, compares it with the previous file:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">prev_file</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">IFS</span><span style="color: #D4D4D4">= </span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">line</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$line</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">$filename</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">prev_file</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$line</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">break</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span><span style="color: #D4D4D4"> &lt;&lt;&lt;</span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-l</span><span style="color: #CE9178"> /path/to/directory </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tail</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-n</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178">)&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ -z </span><span style="color: #9CDCFE">$prev_file</span><span style="color: #D4D4D4"> || </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$f</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">prev_file</span><span style="color: #CE9178">}&quot;</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># If the file is deleted, nothing to do. If not, deletes it:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ -z </span><span style="color: #9CDCFE">$prev_file</span><span style="color: #D4D4D4"> ]] || [[ </span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s ${</span><span style="color: #9CDCFE">filename</span><span style="color: #CE9178">})&quot;</span><span style="color: #D4D4D4"> == </span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s ${</span><span style="color: #9CDCFE">prev_file</span><span style="color: #CE9178">})&quot;</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">/path/to/directory/</span><span style="color: #9CDCFE">$filename</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Nous chargeons le <a href="https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF" target="_blank" rel="noreferrer noopener">modèle DeepSeek de 6,7 milliards de paramètres</a> dans LocalAI sur une VM Debian dans Proxmox. La VM se voit allouer beaucoup de mémoire vive et 12 cœurs du micro-processeur AMD Threadripper 3960X sous-jacent (24 cœurs au total mais pas de support AVX-512). Nous créons ainsi à un rythme d&#8217;environ 3 lignes par seconde le résultat suivant :&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

# Check if directory is provided
if [ $# -ne 1 ]; then
  echo &quot;Usage: $0 directory&quot;
    exit 1
fi

# Check if directory exists
if [&nbsp;! -d &quot;$1&quot; ]; then
    echo &quot;Directory $1 does not exist&quot;
    exit 1
fi

# Change to the directory
cd &quot;$1&quot;

# Get the list of files in order of creation date
files=$(ls -t)

# Initialize previous_size to 0
previous_size=0

# Iterate over the files
for file in $files; do
    # Get the size of the file
    size=$(stat -c%s &quot;$file&quot;)

    # If the size is equal to the previous size, delete the file
    if [ $size -eq $previous_size ]; then
        rm &quot;$file&quot;
        echo &quot;Deleted $file&quot;
    fi

    # Update previous_size
    previous_size=$size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Check if directory is provided</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #569CD6">$#</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Usage: </span><span style="color: #9CDCFE">$0</span><span style="color: #CE9178"> directory&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Check if directory exists</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [&nbsp;! -d </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Directory </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178"> does not exist&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Change to the directory</span></span>
<span class="line"><span style="color: #DCDCAA">cd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Get the list of files in order of creation date</span></span>
<span class="line"><span style="color: #9CDCFE">files</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-t</span><span style="color: #CE9178">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Initialize previous_size to 0</span></span>
<span class="line"><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Iterate over the files</span></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$files</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Get the size of the file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c%s</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># If the size is equal to the previous size, delete the file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$size</span><span style="color: #D4D4D4"> -eq </span><span style="color: #9CDCFE">$previous_size</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Deleted </span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Update previous_size</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Enfin, sur la même VM, nous pouvons également essayer Mistral, pour lequel nous choisissons au hasard la version <a href="https://huggingface.co/TheBloke/Mistral-7B-Code-16K-qlora-GGUF" target="_blank" rel="noreferrer noopener">mistral-7B-code-16K-qlora</a> qui a été légèrement adaptée par <em>fine-tuning</em> pour le code par un internaute. Il s&#8217;avère que sa réponse est rapide, générant le résultat compact suivant en quelque 2 secondes (malheureusement sans documentation, et en proposant la commande complexe <em>awk</em> ) :&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="for file in $(find directory -type f -exec du -sh {} + | sort -h | awk '{print NR &quot;:\t&quot; $1}'); do
    size=$(du -sh &quot;$file&quot; | awk '{print $1}')
    if [[ $size == $previous_size ]]; then
      rm &quot;$file&quot;
    fi
    previous_size=$size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">find</span><span style="color: #CE9178"> directory </span><span style="color: #569CD6">-type</span><span style="color: #CE9178"> f </span><span style="color: #569CD6">-exec</span><span style="color: #CE9178"> du </span><span style="color: #569CD6">-sh</span><span style="color: #CE9178"> {} + </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">sort</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-h</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> &#39;{print NR &quot;:\t&quot; $1}&#39;)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">du</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-sh</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> &#39;{print $1}&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$size</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">$previous_size</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Je laisse volontiers au lecteur le soin de procéder à une comparaison plus approfondie de ces résultats. Si nous devons tirer une dernière leçon de cette expérience, c&#8217;est que même si les modèles ont le même nombre de paramètres et sont entraînés dans le même but, il peut y avoir de très grandes différences de résultat et de style entre eux&nbsp;! &nbsp;</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>À la vitesse de l&#8217;éclair, toutes sortes de fonctions alimentées par l&#8217;IA trouvent leur place dans l&#8217;IDE. Les <a href="https://code.visualstudio.com/updates/v1_87" target="_blank" rel="noreferrer noopener">dernières notes de mises à jour de Visual Studio Code</a> mentionnent, par exemple, la prise en charge de la reconnaissance vocale dans plusieurs langues, en plus de plusieurs fonctionnalités de CoPilot. En tant que développeur, il est inévitable que vous soyez confronté à cette situation. Les développeurs qui travaillent avec des données sensibles ou du code protégé par des droits d&#8217;auteur doivent se méfier à juste titre de ces outils qui envoient le contenu de leur IDE à un service cloud tiers pour proposer des suggestions.&nbsp;&nbsp;</p>



<p>Grâce notamment au projet <a href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noreferrer noopener">llama.cpp</a>, une voie alternative open source a récemment vu le jour, qui permet de mettre en place et d&#8217;exploiter soi-même une telle assistance au codage avec des LLM. Les modèles plus petits qui peuvent fonctionner sur du matériel grand public n&#8217;offrent actuellement pas la même qualité et la même vitesse que Github CoPilot ou ChatGPT. Toutefois, de nouvelles améliorations apparaîtront régulièrement au cours des prochaines années, de sorte que la voie à suivre semble prometteuse à tous points de vue.&nbsp;&nbsp;</p>



<p>______________________</p>



<p><em><em>Ce post est une contribution individuelle de Joachim Ganseman, spécialisée en intelligence artificielle chez Smals Research. Cet article est écrit en son nom propre et n’impacte en rien le point de vue de Smals.</em></em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Aan de slag met open source coding assistants</title>
		<link>https://www.smalsresearch.be/opensource-coding-assistants/</link>
		
		<dc:creator><![CDATA[Joachim Ganseman]]></dc:creator>
		<pubDate>Mon, 11 Mar 2024 15:42:44 +0000</pubDate>
				<category><![CDATA[[NL]]]></category>
		<category><![CDATA[Blog post]]></category>
		<category><![CDATA[Artificial intelligence]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[computational creativity]]></category>
		<category><![CDATA[egov]]></category>
		<category><![CDATA[Natural Language Processing]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">/?p=20178</guid>

					<description><![CDATA[Een privacyvriendelijke coding assistant voor een IDE met open source tools - hoe doe je dat?]]></description>
										<content:encoded><![CDATA[
<p><em>Cet article est aussi disponible <a href="/opensource-coding-assistants-fr/">en français</a>.</em></p>



<p>Als code-genererend hulpmiddel voor softwareontwikkelaars domineert <a href="https://github.com/features/copilot">Github Copilot</a> vandaag de markt. Dat zal wellicht nog wel even aanhouden, zeker nu de tool ook wordt uitgebreid met chatfunctionaliteit à la ChatGPT. Als eigendom van Microsoft, geniet Github van een directe lijn met OpenAI en zo kan het als eerste meegenieten van de voortrekkersrol die dat bedrijf blijft spelen inzake de ontwikkeling van <a href="https://en.wikipedia.org/wiki/Large_language_model">Large Language Models (LLMs)</a>.</p>



<p>Men zou haast vergeten dat er ook andere mogelijkheden zijn. Het eerste grootschalige alternatief dat van de grond af open-source was opgebouwd, inclusief <a href="https://huggingface.co/datasets/bigcode/the-stack">open trainingsdata</a>, is <a href="https://huggingface.co/blog/starcoder">StarCoder</a>, waar sinds kort ook een <a href="https://github.com/bigcode-project/starcoder2">versie 2</a> van is uitgekomen. Het wordt ontwikkeld onder het <a href="https://www.bigcode-project.org/">BigCode initiatief</a> van ServiceNow en HuggingFace. De <a href="https://arxiv.org/abs/2305.06161">bijhorende paper </a>geeft een fascinerende inkijk in de opbouw van een taalmodel voor het genereren van code. Kort na StarCoder verschenen <a href="https://arxiv.org/abs/2306.08568">WizardCoder</a>, <a href="https://arxiv.org/abs/2308.12950">CodeLLama</a>, <a href="https://github.com/deepseek-ai/DeepSeek-Coder">DeepSeekCoder</a> en nog enkele anderen ten tonele &#8211; niet allemaal met een open dataset erachter, maar wel vrij toegankelijk en herbruikbaar via <a href="https://huggingface.co/">HuggingFace</a>. </p>



<p>Ondertussen is er voldoende tooling beschikbaar om deze modellen gemakkelijker op een eigen machine te draaien. &#8220;Your Own Personal Coding Assistant&#8221;, self-hosted en volledig privaat, is vandaag haalbare kaart. We hebben daarvoor nodig: voldoende krachtige hardware, een LLM toegespitst op <em>code completion</em> taken of op conversaties over code, en een plugin voor de IDE. LLM en IDE plugin spreken met elkaar via een API, die al dan niet compatibel kan zijn met die van OpenAI &#8211; wat desgewenst toelaat gemakkelijk te wisselen tussen commerciële (OpenAI) en open source modellen.</p>



<h2 class="wp-block-heading">IDE plugins</h2>



<p>Een plugin installeren is op zich gemakkelijk. Github Copilot bestaat al langer als <a href="https://code.visualstudio.com/docs/editor/github-copilot">plugin voor VSCode</a> en vandaag ook voor <a href="https://plugins.jetbrains.com/plugin/17718-github-copilot">IntelliJ IDEA</a> &#8211; al bevat de IntelliJ versie op moment van schrijven nog wat minder  functionaliteit. </p>



<p>Onder de open-source alternatieven hoort <a href="https://continue.dev/">Continue</a> momenteel waarschijnlijk bij de top. Er zijn er andere – Huggingface zelf heeft bijvoorbeeld <a href="https://github.com/huggingface/llm-vscode?tab=readme-ov-file">llm-vscode</a> ontwikkeld – en ongetwijfeld zullen er nog bijkomen. Net zoals Github Copilot bestaat Continue ook als <a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue">plugin voor VSCode</a> of <a href="https://plugins.jetbrains.com/plugin/22707-continue">IntelliJ</a>. Het kan zowel gebruikmaken van commerciële cloud-based generatoren (waaronder GPT-4) als van zelf gehoste open-source oplossingen. Die hoeven niet noodzakelijk de OpenAI API na te volgen, en er is veel customizatie mogelijk.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/03/2024-03-11_14h59_32.png"><img loading="lazy" decoding="async" width="1024" height="410" src="/wp-content/uploads/2024/03/2024-03-11_14h59_32-1024x410.png" alt="" class="wp-image-20216" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-1024x410.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-300x120.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-768x308.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32-1536x615.png 1536w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_14h59_32.png 1858w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Screenshot van de Continue plugin in Visual Studio Code</figcaption></figure>



<p>Het blijft belangrijk om tijd te investeren om met de plugin te leren werken. De <a href="https://continue.dev/docs/intro">documentatie van Continue</a> is een goed startpunt. Voor elke <a href="https://continue.dev/docs/model-setup/select-provider">server</a> en elke <a href="https://continue.dev/docs/model-setup/select-model">LLM</a> kunnen er andere configuratieopties zijn die ingesteld moeten worden, en misschien wil je custom aanpassingen maken aan de achterliggende <a href="https://continue.dev/docs/model-setup/configuration">prompt</a>. Daarnaast is het nodig om te weten hoe de plugin geactiveerd en gedeactiveerd kan worden in de IDE, en welke shortcuts en <a href="https://continue.dev/docs/customization/slash-commands">commando&#8217;s</a> er bestaan. <a href="https://www.youtube.com/results?search_query=continue+ai">YouTube</a> kan een goed startpunt zijn om tutorials en voorbeelden van andere gebruikers te vinden.</p>



<h2 class="wp-block-heading">Een LLM op je laptop</h2>



<p>Vooral onder impuls van het open-source project <a href="https://github.com/ggerganov/llama.cpp">llama.cpp</a>, zijn er het afgelopen jaar enorme inspanningen gebeurd om LLMs ook inzetbaar te maken op gewone consumentenhardware. Een peperdure GPU is niet meer noodzakelijk, al gaat het met GPU wel nog steeds sneller. In grote lijnen laat <a href="https://github.com/ggerganov/llama.cpp">llama.cpp</a> toe om een model te herverpakken in het GGUF formaat (GPT-Generated Unified Format). Daarbij worden zoveel mogelijk optimalisaties toegepast:</p>



<ul class="wp-block-list">
<li>gebruik van efficiënte CPU-instructiesets zoals <a href="https://en.wikipedia.org/wiki/AVX-512">AVX-512</a> &#8211; het spreekt voor zich dat de hardware waarop het model later moet draaien, deze instructiesets ook moet ondersteunen,</li>



<li>gebruik van sterk geoptimaliseerde high-performance libraries voor de achterliggende berekeningen, zoals <a href="https://github.com/OpenMathLib/OpenBLAS">openBLAS</a> of Apples <a href="https://developer.apple.com/documentation/accelerate">Accelerate</a> en <a href="https://developer.apple.com/metal/">Metal</a>,</li>



<li>het <em>kwantiseren </em>van het model, door het reduceren van de <a href="https://en.wikipedia.org/wiki/Precision_(computer_science)">precisie</a> van de gewichten in de lagen van de neurale netwerken. De 16-bit of 32-bit (komma)getallen uit het originele model worden daarbij omgezet naar gehele getallen (integers) van 8-bit, zelfs 6-bit of 4-bit. Dit bespaart geheugen en versnelt de berekeningen, ten koste van een relatief klein kwaliteitsverlies.</li>
</ul>



<p>Lokaal een LLM hosten kan met tools zoals <a href="https://lmstudio.ai/">LM Studio</a>. Die geven je de mogelijkheid om verschillende modellen te downloaden in GGUF formaat. Een apart tabblad in de applicatie laat toe om een HTTP Inference server rond een gedownload en ingeladen model op te starten, die de API van OpenAI simuleert. Eens deze opgezet is, bijvoorbeeld op poort 1234, is het model aanspreekbaar via een call naar  <code>http://localhost:1234/v1/chat/completions</code> . </p>



<p>Dit instellen in de Continue plugin gebeurt door de LLM toe te voegen aan het bestand <code>.continue/config.json</code> , volgens <a href="https://docs.continue.dev/customize">deze instructies</a> en volgens de richtlijnen voor <a href="https://docs.continue.dev/customize/model-providers/more/lmstudio">LM Studio als model provider</a>. Daarbij kan je de titel en het model aanpassen naar eigen goeddunken, en hoef je enkel nog de lijn <code>"apiBase":"http://127.0.0.1:1234/v1"</code> toe te voegen. In de plugin zal je dit dan als nieuwe keuzemogelijkheid zien verschijnen, en kan je ermee aan de slag.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2024/03/2024-03-11_15h06_39.png"><img loading="lazy" decoding="async" width="1024" height="550" src="/wp-content/uploads/2024/03/2024-03-11_15h06_39-1024x550.png" alt="" class="wp-image-20217" srcset="https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-1024x550.png 1024w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-300x161.png 300w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-768x412.png 768w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39-1536x825.png 1536w, https://www.smalsresearch.be/wp-content/uploads/2024/03/2024-03-11_15h06_39.png 1918w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">LM Studio, met het CodeNinja model ingeladen, beantwoordt een query via de ingebouwde server die actief is op poort 1234. </figcaption></figure>



<h2 class="wp-block-heading">Intermezzo: over hardware</h2>



<p>Het beheer van GPU&#8217;s is al geen pretje voor 1 developer aan 1 machine. Incompatibiliteitsproblemen tussen verschillende versies van allerlei software libraries en GPU-drivers kunnen dagen duren om op te lossen. Het <a href="https://www.nvidia.com/en-us/data-center/products/">marktaanbod van GPUs voor datacenters</a>, gedomineerd door nVIDIA in een monopoliepositie, is onnoemelijk duur. Daarbij komt nog de kost van het opbouwen van de heel gespecialiseerde kennis die nodig is om die systemen draaiende te houden. Eender wat je kiest van hardware is over 4 jaar waarschijnlijk al helemaal verouderd. Er wordt hard gewerkt aan nieuwe hardware, specifiek gemaakt om het soort berekeningen van AI-modellen te versnellen &#8211; Google kwam eerder al met de <a href="https://en.wikipedia.org/wiki/Tensor_Processing_Unit">TPU</a>, maar andere fabrikanten zetten nu ook hard in op <a href="https://www.techradar.com/computing/cpu/what-is-an-npu">NPUs (Neural Processing Units)</a>, en sommigen durven <a href="https://www.cerebras.net/">directe concurrentie</a> aan met nVIDIA. </p>



<p>Als je geen tijd hebt om te knoeien met GPU-drivers en niet de ambitie hebt om zelf modellen te trainen, dan is de mogelijkheid om ze te gebruiken op een gewone CPU meer dan welkom. Uiteraard ben je dan wel beperkt tot die LLMs of AI-modellen waarvan de grootte dat ook toelaat. Typische LLMs voor &#8220;thuisgebruik&#8221; hebben 3, 7 of 13 miljard parameters; grotere modellen worden <a href="https://github.com/ggerganov/llama.cpp#memorydisk-requirements">agressief gekwantiseerd</a> om schijfruimte en geheugen te besparen. Ze gaan vandaag nog niet kunnen tippen aan de kwaliteit van GPT-4, maar er bestaan gelukkig leaderboards om te helpen een keuze te maken &#8211; voor <a href="https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard">open LLMs in het algemeen</a>, specifiek met <a href="https://huggingface.co/spaces/optimum/llm-perf-leaderboard">(doorvoer)snelheidsbenchmarks</a>, of voor <a href="https://huggingface.co/spaces/bigcode/bigcode-models-leaderboard">code-genererende LLMs</a> in het bijzonder.</p>



<p>Hoe groter de LLMs, hoe kwaliteitsvoller het resultaat (meestal), maar ook hoe meer geheugen en rekenkracht vereist is. Een LLM moet liefst volledig in het geheugen ingeladen kunnen worden, dus 16GB RAM is geen luxe &#8211; meer is beter, zeker als je een IDE op dezelfde machine wil draaien. Om een antwoord te kunnen te geven, moet het volledige model vaak meermaals doorlopen worden. De bottleneck wordt bijgevolg vaak gevormd door de bandbreedte tussen CPU en RAM. CPUs met een grote interne cache lijken een streepje voor te hebben (zie ook AI-specifieke benchmarks [<a href="https://www.anandtech.com/show/21084/intel-core-i9-14900k-core-i7-14700k-and-core-i5-14600k-review-raptor-lake-refreshed/10">1</a>,<a href="https://www.anandtech.com/show/21242/amd-ryzen-7-8700g-and-ryzen-5-8600g-review/8">2</a>] van Anandtech). Bij de keuze van de rest van de hardware moet geheugenbandbreedte zeker meespelen. Ook wie een GPU zou willen kiezen, kijkt misschien liever naar die bandbreedte dan naar het aantal cores. Tot slot is het in gevirtualiseerde omgevingen (een VM, een VPS) belangrijk dat de virtuele CPU dezelfde geavanceerde instructiesets, zoals <a href="https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512">AVX-512</a>, ondersteunt.</p>



<h2 class="wp-block-heading">Een LLM op je server</h2>



<p>Als je elders een krachtigere machine hebt, kan het de moeite waard zijn om de LLM daarop te draaien. <a href="https://ollama.com/">ollama</a> is waarschijnlijk de populairste tool om zonder veel poespas modellen te hosten op Mac of Linux, sinds kort ook Windows. <a href="https://localai.io/">LocalAI</a> is echter een zeker zo interessante optie uit de lijst van mogelijke <a href="https://continue.dev/docs/model-setup/select-provider">LLM providers voor Continue</a>, want het biedt Docker containers aan, met of zonder GPU ondersteuning. Op een Linux machine die is uitgerust met Docker, is <a href="https://localai.io/basics/getting_started/">een oneliner</a> in de terminal voldoende om het open-source CodeLlama model te downloaden en te beginnen hosten op poort 1234:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="docker run -ti -p 1234:8080 localai/localai:v2.7.0-ffmpeg-core codellama-7b-gguf " style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">docker</span><span style="color: #000000"> </span><span style="color: #A31515">run</span><span style="color: #000000"> </span><span style="color: #0000FF">-ti</span><span style="color: #000000"> </span><span style="color: #0000FF">-p</span><span style="color: #000000"> </span><span style="color: #098658">1234</span><span style="color: #A31515">:8080</span><span style="color: #000000"> </span><span style="color: #A31515">localai/localai:v2.7.0-ffmpeg-core</span><span style="color: #000000"> </span><span style="color: #A31515">codellama-7b-gguf</span><span style="color: #000000"> </span></span></code></pre></div>



<p></p>



<p>De opstart ervan duurt echter even, want het model wordt in de container gedownload. Interessanter is het om zelf een reeks modellen in een lokale map te bewaren, en daaromheen een API te zetten middels een LocalAI container. Ook voor die aanpak zijn relatief eenvoudige <a href="https://localai.io/docs/getting-started/models/">instructies</a> beschikbaar. We kunnen ze bijvoorbeeld toepassen op de <a href="https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF">DeepSeek LLM van 6.7 miljard parameters, gekwantiseerd op 4 bits</a>. Deze kan rechtstreeks van Huggingface gedownload worden naar de lokale map <code>./models-gguf</code> met een <code>wget</code> commando van het type:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="wget https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF/resolve/main/deepseek-coder-6.7b-instruct.Q4_K_M.gguf -O ./models-gguf/deepseek-6.7b-instruct-Q4" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">wget</span><span style="color: #000000"> </span><span style="color: #A31515">https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF/resolve/main/deepseek-coder-6.7b-instruct.Q4_K_M.gguf</span><span style="color: #000000"> </span><span style="color: #0000FF">-O</span><span style="color: #000000"> </span><span style="color: #A31515">./models-gguf/deepseek-6.7b-instruct-Q4</span></span></code></pre></div>



<p></p>



<p>Een API starten rondom de modellen in die map op poort 8001 (je kan ook meerdere modellen in dezelfde map zetten en ze tegelijk hosten), kan dan met het volgende commando. Voeg eventueel <code><em>-d</em></code> toe om het in de achtergrond te laten lopen, en voel je vrij om met de parameters <code><em>context-size</em></code> en <code><em>threads </em></code>te experimenteren in functie van hoe krachtig je server is: </p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="docker run -p 8001:8080 -v $PWD/models-gguf:/models -ti --rm quay.io/go-skynet/local-ai:v2.7.0-ffmpeg-core --models-path /models --context-size 1600 --threads 16" style="color:#000000;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">docker</span><span style="color: #000000"> </span><span style="color: #A31515">run</span><span style="color: #000000"> </span><span style="color: #0000FF">-p</span><span style="color: #000000"> </span><span style="color: #098658">8001</span><span style="color: #A31515">:8080</span><span style="color: #000000"> </span><span style="color: #0000FF">-v</span><span style="color: #000000"> </span><span style="color: #001080">$PWD</span><span style="color: #A31515">/models-gguf:/models</span><span style="color: #000000"> </span><span style="color: #0000FF">-ti</span><span style="color: #000000"> </span><span style="color: #0000FF">--rm</span><span style="color: #000000"> </span><span style="color: #A31515">quay.io/go-skynet/local-ai:v2.7.0-ffmpeg-core</span><span style="color: #000000"> </span><span style="color: #0000FF">--models-path</span><span style="color: #000000"> </span><span style="color: #A31515">/models</span><span style="color: #000000"> </span><span style="color: #0000FF">--context-size</span><span style="color: #000000"> </span><span style="color: #098658">1600</span><span style="color: #000000"> </span><span style="color: #0000FF">--threads</span><span style="color: #000000"> </span><span style="color: #098658">16</span></span></code></pre></div>



<p></p>



<h2 class="wp-block-heading">Voorbeeld</h2>



<p>We kunnen nu verschillende LLMs voor code met elkaar vergelijken. We houden het hier louter anekdotisch, en nemen als eenvoudig voorbeeld het schrijven van een <em>bash </em>shellscript. We vertrekken van het volgende probleem: een backup-routine heeft jarenlang een nachtelijke backup genomen van een systeem. Om schijfruimte vrij te maken, willen we alle backups verwijderen die niet verschillen van de vorige. We geven de volgende opdracht, waarbij we de taak zo nauwgezet mogelijk omschrijven voor het beste resultaat: <em>&#8220;Write a bash script that, given a directory, iterates over all its files in order of date of creation. For each file, if the filesize is equal to the filesize of the previous file, the file has to be deleted.&#8221;</em></p>



<p>De <code>.continue/config.json</code> file van onze Continue plugin bevat de volgende lijst modellen: eentje op de eigen laptop in LM Studio ingeladen op poort 1234, en twee op een aparte server in het lokaal netwerk, door LocalAI gehost op poort 8001.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="    {
      &quot;title&quot;: &quot;myLaptop-LMStudio&quot;,
      &quot;model&quot;: &quot;whatever is loaded in LMstudio&quot;,
      &quot;apiBase&quot;: &quot;http://127.0.0.1:1234/v1&quot;,
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;lmstudio&quot;
    },       
    {
      &quot;title&quot;: &quot;localAI-mistral&quot;,
      &quot;model&quot;: &quot;mistral-7b-code16kqlora-Q4&quot;,
      &quot;apiBase&quot;: &quot;https://192.168.0.100:8001/v1&quot;,
      &quot;apiKey&quot;: &quot;&quot;,      
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;openai&quot;
    },
    {
      &quot;title&quot;: &quot;localAI-deepseek&quot;,
      &quot;model&quot;: &quot;deepseek-6.7b-instruct-Q4&quot;,
      &quot;apiBase&quot;: &quot;https://192.168.0.100:8001/v1&quot;,
      &quot;apiKey&quot;: &quot;&quot;,
      &quot;completionOptions&quot;: {},
      &quot;provider&quot;: &quot;openai&quot;
    }," style="color:#24292e;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki github-light" style="background-color: #fff" tabindex="0"><code><span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;myLaptop-LMStudio&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;whatever is loaded in LMstudio&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;http://127.0.0.1:1234/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;lmstudio&quot;</span></span>
<span class="line"><span style="color: #24292E">    },       </span></span>
<span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;localAI-mistral&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;mistral-7b-code16kqlora-Q4&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;https://192.168.0.100:8001/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiKey&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;&quot;</span><span style="color: #24292E">,      </span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;openai&quot;</span></span>
<span class="line"><span style="color: #24292E">    },</span></span>
<span class="line"><span style="color: #24292E">    {</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;title&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;localAI-deepseek&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;model&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;deepseek-6.7b-instruct-Q4&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiBase&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;https://192.168.0.100:8001/v1&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;apiKey&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;&quot;</span><span style="color: #24292E">,</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;completionOptions&quot;</span><span style="color: #24292E">: {},</span></span>
<span class="line"><span style="color: #24292E">      </span><span style="color: #032F62">&quot;provider&quot;</span><span style="color: #24292E">: </span><span style="color: #032F62">&quot;openai&quot;</span></span>
<span class="line"><span style="color: #24292E">    },</span></span></code></pre></div>



<p></p>



<p>Als referentie nemen we <a href="https://chat.openai.com/">ChatGPT</a>, die komt met de volgende (correcte) oplossing. Bovendien wordt ze ook gevolgd door een uitgebreide uitleg over wat de verschillende onderdelen betekenen (hier niet weergegeven):</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

# Directory containing the files
DIR=&quot;/path/to/your/directory&quot;

# Variable to hold the size of the previous file. Initialized to 0.
prev_size=0

# List all files in the directory, sorted by creation date
# Note: '%T@' sorts by creation time, '%p' prints the file's name
# 'sort -n' ensures the list is sorted numerically
# Note that creation time sorting may depend on filesystem and OS support
files=$(find &quot;$DIR&quot; -type f -printf &quot;%T@ %p\n&quot; | sort -n | cut -d ' ' -f 2-)

# Iterate over the sorted list of files
for file in $files; do
  # Get current file size
  current_size=$(stat -c %s &quot;$file&quot;)
  
  # Check if current file size is equal to the previous file's size
  if [ &quot;$current_size&quot; -eq &quot;$prev_size&quot; ]; then
    # Sizes are equal, delete the current file
    echo &quot;Deleting file: $file&quot;
    rm &quot;$file&quot;
  fi
  
  # Update previous size to current file's size
  prev_size=$current_size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Directory containing the files</span></span>
<span class="line"><span style="color: #9CDCFE">DIR</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;/path/to/your/directory&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Variable to hold the size of the previous file. Initialized to 0.</span></span>
<span class="line"><span style="color: #9CDCFE">prev_size</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># List all files in the directory, sorted by creation date</span></span>
<span class="line"><span style="color: #6A9955"># Note: &#39;%T@&#39; sorts by creation time, &#39;%p&#39; prints the file&#39;s name</span></span>
<span class="line"><span style="color: #6A9955"># &#39;sort -n&#39; ensures the list is sorted numerically</span></span>
<span class="line"><span style="color: #6A9955"># Note that creation time sorting may depend on filesystem and OS support</span></span>
<span class="line"><span style="color: #9CDCFE">files</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">find</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$DIR</span><span style="color: #CE9178">&quot; </span><span style="color: #569CD6">-type</span><span style="color: #CE9178"> f </span><span style="color: #569CD6">-printf</span><span style="color: #CE9178"> &quot;%T@ %p\n&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">sort</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-n</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">cut</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-d</span><span style="color: #CE9178"> &#39; &#39; </span><span style="color: #569CD6">-f</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178">-)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Iterate over the sorted list of files</span></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$files</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Get current file size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">current_size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;)</span></span>
<span class="line"><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Check if current file size is equal to the previous file&#39;s size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$current_size</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> -eq </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$prev_size</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Sizes are equal, delete the current file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Deleting file: </span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955"># Update previous size to current file&#39;s size</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">prev_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$current_size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>In LMStudio laden we het model &#8220;<a href="https://huggingface.co/TheBloke/CodeNinja-1.0-OpenChat-7B-GGUF">CodeNinja 1.0 openchat 7B Q4_K_M</a>&#8221; in. Voor het genereren van het antwoord op dezelfde vraag is ruim 1 minuut nodig: 20 seconden wachten tot de eerste letter van het antwoord verschijnt, daarna nog ongeveer 2 seconden per lijn. (Onze laptop is natuurlijk niet superkrachtig: een Core i7-10610U CPU met 32GB RAM). Het volgende komt eruit:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

for f in $(ls -t -l --time-style=full /path/to/directory)
do
  if [[ $f == &quot;total&quot;* ]]; then
        continue;
    fi
    filename=$(basename &quot;${f% *}&quot;)

    # Checks whether the file is already deleted. If not, compares it with the previous file:
    prev_file=&quot;&quot;
    while IFS= read -r line; do
        if [[ $line == $filename ]]; then
            prev_file=$line
            break;
        fi
    done &lt;&lt;&lt;&quot;$(ls -l /path/to/directory | tail -n 2)&quot;

    if [[ -z $prev_file || &quot;$f&quot; = &quot;${prev_file}&quot; ]]; then
        # If the file is deleted, nothing to do. If not, deletes it:
        if [[ -z $prev_file ]] || [[ &quot;$(stat -c %s ${filename})&quot; == &quot;$(stat -c %s ${prev_file})&quot; ]]; then
            rm /path/to/directory/$filename
        fi
    fi
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">f</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-t</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-l</span><span style="color: #CE9178"> </span><span style="color: #569CD6">--time-style=full</span><span style="color: #CE9178"> /path/to/directory)</span></span>
<span class="line"><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$f</span><span style="color: #D4D4D4"> == </span><span style="color: #CE9178">&quot;total&quot;</span><span style="color: #D4D4D4">* ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">continue</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">filename</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">basename</span><span style="color: #CE9178"> &quot;${</span><span style="color: #9CDCFE">f</span><span style="color: #D4D4D4">%</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">*</span><span style="color: #CE9178">}&quot;)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Checks whether the file is already deleted. If not, compares it with the previous file:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">prev_file</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">IFS</span><span style="color: #D4D4D4">= </span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-r</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">line</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$line</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">$filename</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">prev_file</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$line</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">break</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">done</span><span style="color: #D4D4D4"> &lt;&lt;&lt;</span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-l</span><span style="color: #CE9178"> /path/to/directory </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">tail</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-n</span><span style="color: #CE9178"> </span><span style="color: #B5CEA8">2</span><span style="color: #CE9178">)&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ -z </span><span style="color: #9CDCFE">$prev_file</span><span style="color: #D4D4D4"> || </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$f</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;${</span><span style="color: #9CDCFE">prev_file</span><span style="color: #CE9178">}&quot;</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #6A9955"># If the file is deleted, nothing to do. If not, deletes it:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ -z </span><span style="color: #9CDCFE">$prev_file</span><span style="color: #D4D4D4"> ]] || [[ </span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s ${</span><span style="color: #9CDCFE">filename</span><span style="color: #CE9178">})&quot;</span><span style="color: #D4D4D4"> == </span><span style="color: #CE9178">&quot;$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c</span><span style="color: #CE9178"> %s ${</span><span style="color: #9CDCFE">prev_file</span><span style="color: #CE9178">})&quot;</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">/path/to/directory/</span><span style="color: #9CDCFE">$filename</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Het <a href="https://huggingface.co/TheBloke/deepseek-coder-6.7B-instruct-GGUF">DeepSeek model van 6.7 miljard parameters</a> laden we in LocalAI op een Debian VM in Proxmox. Aan de VM is ruim voldoende RAM toegekend, en 12 cores van de onderliggende hardware, een AMD Threadripper 3960X processor (24 cores maar geen AVX-512 ondersteuning). Hiermee creëren we aan een snelheid van ongeveer 3 lijnen per seconde het volgende resultaat:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="#!/bin/bash

# Check if directory is provided
if [ $# -ne 1 ]; then
  echo &quot;Usage: $0 directory&quot;
    exit 1
fi

# Check if directory exists
if [&nbsp;! -d &quot;$1&quot; ]; then
    echo &quot;Directory $1 does not exist&quot;
    exit 1
fi

# Change to the directory
cd &quot;$1&quot;

# Get the list of files in order of creation date
files=$(ls -t)

# Initialize previous_size to 0
previous_size=0

# Iterate over the files
for file in $files; do
    # Get the size of the file
    size=$(stat -c%s &quot;$file&quot;)

    # If the size is equal to the previous size, delete the file
    if [ $size -eq $previous_size ]; then
        rm &quot;$file&quot;
        echo &quot;Deleted $file&quot;
    fi

    # Update previous_size
    previous_size=$size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">#!/bin/bash</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Check if directory is provided</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #569CD6">$#</span><span style="color: #D4D4D4"> -ne </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Usage: </span><span style="color: #9CDCFE">$0</span><span style="color: #CE9178"> directory&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Check if directory exists</span></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [&nbsp;! -d </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Directory </span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178"> does not exist&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">exit</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Change to the directory</span></span>
<span class="line"><span style="color: #DCDCAA">cd</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$1</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Get the list of files in order of creation date</span></span>
<span class="line"><span style="color: #9CDCFE">files</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">ls</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-t</span><span style="color: #CE9178">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Initialize previous_size to 0</span></span>
<span class="line"><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># Iterate over the files</span></span>
<span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$files</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Get the size of the file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">stat</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-c%s</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># If the size is equal to the previous size, delete the file</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [ </span><span style="color: #9CDCFE">$size</span><span style="color: #D4D4D4"> -eq </span><span style="color: #9CDCFE">$previous_size</span><span style="color: #D4D4D4"> ]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">echo</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Deleted </span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># Update previous_size</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Tot slot kunnen we op dezelfde VM ook het recentere Mistral uitproberen, waarvoor we op goed geluk de versie <a href="https://huggingface.co/TheBloke/Mistral-7B-Code-16K-qlora-GGUF">mistral-7B-code-16K-qlora</a> uitkiezen die door een andere gebruiker lichtjes werd bijgetraind voor code. Deze blijkt zeer snel te kunnen antwoorden, en genereert in ongeveer 2 seconden het volgende compacte resultaat (helaas zonder documentatie, en gebruikmakend van het complexe <em>awk</em> commando):</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.75rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="for file in $(find directory -type f -exec du -sh {} + | sort -h | awk '{print NR &quot;:\t&quot; $1}'); do
    size=$(du -sh &quot;$file&quot; | awk '{print $1}')
    if [[ $size == $previous_size ]]; then
      rm &quot;$file&quot;
    fi
    previous_size=$size
done" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">file</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">in</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">find</span><span style="color: #CE9178"> directory </span><span style="color: #569CD6">-type</span><span style="color: #CE9178"> f </span><span style="color: #569CD6">-exec</span><span style="color: #CE9178"> du </span><span style="color: #569CD6">-sh</span><span style="color: #CE9178"> {} + </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">sort</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-h</span><span style="color: #CE9178"> </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> &#39;{print NR &quot;:\t&quot; $1}&#39;)</span><span style="color: #D4D4D4">; </span><span style="color: #C586C0">do</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">size</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">$(</span><span style="color: #DCDCAA">du</span><span style="color: #CE9178"> </span><span style="color: #569CD6">-sh</span><span style="color: #CE9178"> &quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot; </span><span style="color: #D4D4D4">|</span><span style="color: #CE9178"> </span><span style="color: #DCDCAA">awk</span><span style="color: #CE9178"> &#39;{print $1}&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> [[ </span><span style="color: #9CDCFE">$size</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">$previous_size</span><span style="color: #D4D4D4"> ]]; </span><span style="color: #C586C0">then</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;</span><span style="color: #9CDCFE">$file</span><span style="color: #CE9178">&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">fi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">previous_size</span><span style="color: #D4D4D4">=</span><span style="color: #9CDCFE">$size</span></span>
<span class="line"><span style="color: #C586C0">done</span></span></code></pre></div>



<p></p>



<p>Ik laat de diepgaandere vergelijking van deze resultaten graag over als oefening aan de lezer. Als we hieruit nog een laatste les moeten leren, dan is het dat er ook tussen modellen onderling, zelfs al hebben ze dezelfde hoeveelheid parameters en zijn ze voor hetzelfde doel getraind, erg grote verschillen kunnen zijn qua output en stijl! </p>



<h2 class="wp-block-heading">Conclusie</h2>



<p>Aan sneltempo vinden allerlei AI-powered features hun weg naar de IDE. De <a href="https://code.visualstudio.com/updates/v1_87">laatste release notes van Visual Studio Code</a> vermelden naast verschillende CoPilot features bijvoorbeeld ook ondersteuning voor spraakherkenning in meerdere talen. Het is onvermijdelijk dat je daar als developer mee in contact zal komen. Developers die werken met gevoelige data of copyrighted code, zijn terecht argwanend over het feit dat zulke tools hun IDE-inhoud naar een of andere clouddienst van een derde partij versturen, om suggesties te kunnen genereren. </p>



<p>Vooral dankzij het <a href="https://github.com/ggerganov/llama.cpp">llama.cpp</a> project, is er recent een alternatieve <em>open-source</em> route ontstaan die toelaat zulke coding assistentie met LLMs zelf op te zetten en uit te baten. Kleinere modellen die op consumentenhardware kunnen draaien, leveren momenteel niet dezelfde kwaliteit en snelheid als Github CoPilot of ChatGPT. De komende jaren zullen we echter regelmatig verdere verbeteringen zien verschijnen, dus de ingezette weg oogt alleszins veelbelovend. </p>



<p>______________________</p>



<p><em>Dit is een ingezonden bijdrage van Joachim Ganseman, IT consultant bij Smals Research. &nbsp;Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals.</em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
