Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 8 Min.

.NET-Anbindung für die Llama-KI

Open-Source-KI auf dem lokalen Gerät nutzen – mit handhabbarem Speicherbedarf und optionalem Zugriff auf externe Datenquellen.
© dotnetpro
Wer die Tech-News von heute verfolgt, stellt schnell fest: Fast jedes Produkt braucht inzwischen einen CoPilot oder ein anderes KI-Gimmick, um im Gespräch zu bleiben. OpenAI und deren KI-Dienst sind weithin bekannt, aber gibt es auch eine Möglichkeit, eine KI „lokal“ – also ohne riesige Rechenzentren im Hintergrund – zu nutzen? Genau hier kommt LLamaSharp ins Spiel.

Was ist Llama?

Llama ist ein Large Language Model (LLM) von Meta, das ähnliche Funktionen wie das bekannte ChatGPT von OpenAI bietet: Es kann menschliche Sprache verstehen und wiedergeben. Der wesentliche Unterschied zu OpenAI liegt darin, dass Meta sein Modell als Open Source bereitstellt. Dadurch hat sich ein breites Ökosystem rund um Llama entwickelt.Ein zentraler Bestandteil dieses Ökosystems ist die Bibliothek llama.cpp [1], die es ermöglicht, Llama auch auf Geräten mit begrenzten Ressourcen lokal auszuführen. Diese Geräte können zum Beispiel ein Server im heimischen Rack, ein Laptop oder sogar ein Smartphone sein. Für den Hauptentwickler Georgi Gerganov war es von Beginn an wichtig, dass man Llama auch ohne leistungsstarke Grafikkarten direkt auf der CPU nutzen kann – was zur enormen Beliebtheit dieser Bibliothek beigetragen hat.

Das Ökosystem rund um Llama und GGUF

Durch das Open-Source-Modell von Llama und die Vorteile der kostengünstigen Nutzung von llama.cpp sind auch an­dere Sprachmodelle von verschiedenen Firmen entstanden, die mit llama.cpp kompatibel sind. Inzwischen hat sich ein Sprachformat namens GGUF (Grok’s General Unified Format) etabliert. Dieses Format wird von Sprachmodellentwicklern und Tools genutzt und ist mit llama.cpp kompatibel.

LLamaSharp – .NET trifft auf Llama

LLamaSharp [2] basiert auf llama.cpp und stellt dessen Funktionen und APIs als NuGet-Paket für die .NET-Welt bereit. Damit eröffnet LLamaSharp .NET-Entwickler:innen den Zugang zu leistungsfähiger Sprachverarbeitung und KI-Funk­tionen direkt auf ihren Geräten.Ein wichtiger Hinweis vorweg: Dieser Artikel basiert auf der zum Zeitpunkt der Abfassung aktuellen Version 0.18 von LLamaSharp vom Oktober 2024. Das API ist seit einigen Versionen relativ stabil, jedoch handelt es sich bei KI-Themen generell um ein dynamisches und schnelllebiges Umfeld.

Erste Schritte mit LLamaSharp

Die ersten Schritte mit LLamaSharp sind recht schlicht. Es beginnt mit dem NuGet-Package LLamaSharp. Dieses Package bringt Infrastrukturcode und Definitionen mit sich.Um die Modelle auszuführen, verwendet LLamaSharp sogenannte Backends, die so eingesetzt werden sollten, dass sie zur eigenen Software und vor allem Hardware passen. Die Backends nutzen das Kompilat aus dem llama.cpp-Projekt und laufen daher mit der nahezu gleichen Geschwindigkeit wie das native llama.cpp. Folgende Backends sind derzeit für LLamaSharp verfügbar:
  • LLamaSharp.Backend.Cpu: In diesem Backend läuft die Berechnung für Windows und Linux auf der CPU, und für Mac gibt es damit auch direkt Metal-(GPU-)Unterstützung.
  • LLamaSharp.Backend.Cuda11: Für alle GPUs von Nvidia, die CUDA 11 auf Windows und Linux unterstützen
  • LLamaSharp.Backend.Cuda12: Für CUDA-12-GPUs unter Windows und Linux.
  • LLamaSharp.Backend.Vulkan: Für alle Vulkan-fähigen GPUs unter Windows und Linux.
Alle diese Backends stehen als NuGet-Packages bereit und müssen lediglich zum Projekt hinzugefügt werden. Grundsätzlich können auch mehrere Backends hinzugefügt werden (zum Beispiel CPU und CUDA12), sodass LLamaSharp je nach Hardware entweder auf der CPU oder der GPU arbeitet. Mit der Version 0.18 scheint es hierbei jedoch gelegentlich Probleme zu geben, sodass die GPU ignoriert wird, siehe dazu das GitHub-Issue #456 [3].

LLamaSharp-Quickstart

Gehen wir davon aus, dass wir nur mit der CPU arbeiten wollen, so reichen folgende zwei NuGet-Pakete für einen rudimentären Chatbot aus:

dotnet <span class="hljs-built_in">add</span> <span class="hljs-keyword">package</span> LlamaSharp
dotnet <span class="hljs-built_in">add</span> <span class="hljs-keyword">package</span> LLamaSharp.Backend.Cpu 
Der Code in Listing 1 lässt einen Chatbot auf der Kommandozeile entstehen. Hinweis: Der Code entspricht der aktuellen Projekt-ReadMe, allerdings mit einer Fehlerbereinigung. Die InferenceParams müssen unbedingt mit der DefaultSamplingPipeline initialisiert werden, ansonsten kommt es zu einer Null-Reference-Exception.
Listing 1: Ein Chatbot auf der Kommandozeile
using LLama.Common;&lt;br/&gt;using LLama;&lt;br/&gt;string &lt;span class="hljs-attr"&gt;modelPath&lt;/span&gt; = @&lt;span class="hljs-string"&gt;"&amp;lt;Your Model Path&amp;gt;"&lt;/span&gt;; &lt;br/&gt;  // change it to your own model path.&lt;br/&gt;var &lt;span class="hljs-attr"&gt;parameters&lt;/span&gt; = new ModelParams(modelPath)&lt;br/&gt;{&lt;br/&gt;  &lt;span class="hljs-attr"&gt;ContextSize&lt;/span&gt; = &lt;span class="hljs-number"&gt;1024&lt;/span&gt;, &lt;br/&gt;    // The longest length of chat as memory.&lt;br/&gt;  &lt;span class="hljs-attr"&gt;GpuLayerCount&lt;/span&gt; = &lt;span class="hljs-number"&gt;5&lt;/span&gt; &lt;br/&gt;    // How many layers to offload to GPU. Please &lt;br/&gt;    // adjust it according to your GPU memory.&lt;br/&gt;};&lt;br/&gt;using var &lt;span class="hljs-attr"&gt;model&lt;/span&gt; = LLamaWeights.LoadFromFile(parameters);&lt;br/&gt;using var &lt;span class="hljs-attr"&gt;context&lt;/span&gt; = model.CreateContext(parameters);&lt;br/&gt;var &lt;span class="hljs-attr"&gt;executor&lt;/span&gt; = new InteractiveExecutor(context);&lt;br/&gt;// Add chat histories as prompt to tell AI how to act.&lt;br/&gt;var &lt;span class="hljs-attr"&gt;chatHistory&lt;/span&gt; = new ChatHistory();&lt;br/&gt;chatHistory.AddMessage(AuthorRole.System, &lt;br/&gt;  &lt;span class="hljs-string"&gt;"Transcript of a dialog, where the User interacts &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;  with an Assistant named Bob. Bob is helpful, &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;  kind, honest, good at writing, and never fails to &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;  answer the User's requests immediately and with &lt;/span&gt;&lt;br/&gt;&lt;span class="hljs-string"&gt;  precision."&lt;/span&gt;);&lt;br/&gt;chatHistory.AddMessage(&lt;br/&gt;  AuthorRole.User, &lt;span class="hljs-string"&gt;"Hello, Bob."&lt;/span&gt;);&lt;br/&gt;chatHistory.AddMessage(AuthorRole.Assistant, &lt;br/&gt;  &lt;span class="hljs-string"&gt;"Hello. How may I help you today?"&lt;/span&gt;);&lt;br/&gt;ChatSession &lt;span class="hljs-attr"&gt;session&lt;/span&gt; = new(executor, chatHistory);&lt;br/&gt;InferenceParams &lt;span class="hljs-attr"&gt;inferenceParams&lt;/span&gt; = &lt;br/&gt;    new InferenceParams()&lt;br/&gt;{&lt;br/&gt;  &lt;span class="hljs-attr"&gt;SamplingPipeline&lt;/span&gt; = new DefaultSamplingPipeline(), &lt;br/&gt;    // Use default sampling pipeline&lt;br/&gt;  &lt;span class="hljs-attr"&gt;MaxTokens&lt;/span&gt; = &lt;span class="hljs-number"&gt;256&lt;/span&gt;, &lt;br/&gt;    // No more than &lt;span class="hljs-number"&gt;256&lt;/span&gt; tokens should appear &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;br/&gt;    // answer. Remove it &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; antiprompt is enough for &lt;br/&gt;    // control.&lt;br/&gt;  &lt;span class="hljs-attr"&gt;AntiPrompts&lt;/span&gt; = new List&amp;lt;string&amp;gt; { &lt;span class="hljs-string"&gt;"User:"&lt;/span&gt; } &lt;br/&gt;    // Stop generation once antiprompts appear.&lt;br/&gt;  &lt;span class="hljs-attr"&gt;SamplingPipeline&lt;/span&gt; = new DefaultSamplingPipeline(),&lt;br/&gt;};&lt;br/&gt;Console.&lt;span class="hljs-attr"&gt;ForegroundColor&lt;/span&gt; = ConsoleColor.Yellow;&lt;br/&gt;Console.Write(&lt;br/&gt;  &lt;span class="hljs-string"&gt;"The chat session has started.\nUser: "&lt;/span&gt;);&lt;br/&gt;Console.&lt;span class="hljs-attr"&gt;ForegroundColor&lt;/span&gt; = ConsoleColor.Green;&lt;br/&gt;string &lt;span class="hljs-attr"&gt;userInput&lt;/span&gt; = Console.ReadLine() ?? &lt;span class="hljs-string"&gt;""&lt;/span&gt;;&lt;br/&gt;while (userInput != &lt;span class="hljs-string"&gt;"exit"&lt;/span&gt;)&lt;br/&gt;{&lt;br/&gt;  await foreach ( &lt;br/&gt;    // Generate the response streamingly.&lt;br/&gt;    var text&lt;br/&gt;    &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; session.ChatAsync(&lt;br/&gt;      new ChatHistory.Message(AuthorRole.User, &lt;br/&gt;        userInput),&lt;br/&gt;      inferenceParams))&lt;br/&gt;  {&lt;br/&gt;    Console.&lt;span class="hljs-attr"&gt;ForegroundColor&lt;/span&gt; = ConsoleColor.White;&lt;br/&gt;    Console.Write(text);&lt;br/&gt;  }&lt;br/&gt;  Console.&lt;span class="hljs-attr"&gt;ForegroundColor&lt;/span&gt; = ConsoleColor.Green;&lt;br/&gt;  &lt;span class="hljs-attr"&gt;userInput&lt;/span&gt; = Console.ReadLine() ?? &lt;span class="hljs-string"&gt;""&lt;/span&gt;;&lt;br/&gt;} 

Quickstart – Erklärung

Der erste Teil des Codes in Listing 1 bis zur ChatHistory betrifft nur das Laden des Modells. Wie man konkret zu einem Modell kommt und ein passendes auswählt, wird im nächsten Abschnitt beschrieben. Als Einstieg kann man mit den vorgegebenen Werten loslegen, ohne irgendwelche Befürchtungen haben zu müssen, dass das System gleich in die Brüche geht. In ­einer Produktionsumgebung ist jedoch wahrscheinlich eine detailliertere Anpassung erforderlich.Anschließend wird die ChatHistory instanziert. Wer bereits Erfahrungen mit ChatGPT-Einstellungen hat, wird das Muster erkennen: Ein genereller Kontext wird als System-Nachricht festgelegt und definiert die Grundregeln für den Chatbot. Der Assistent repräsentiert den eigentlichen Chatbot, und der Benutzer wird als User bezeichnet. Die ChatHistory dient zur Speicherung des Gesprächsverlaufs und wird der Session übergeben. Die Interaktion mit dem Benutzer erfolgt dann innerhalb der while-Schleife.So viel zum Code, jedoch bleibt die Wahl des Sprachmodells der wichtigste Faktor.

Modellsuche mit LM Studio

Der einfachste Weg, an Modelle zu kommen, führt über LM Studio. Dieses kostenlose Programm läuft sowohl unter Linux und Windows als auch unter macOS und ermöglicht es, lokale LLMs (Large Language Models) herunterzuladen und direkt auf dem eigenen System zu verwenden.Neben den Basisfunktionen bietet LM Studio auch einen integrierten Chatbot, sodass Modelle direkt getestet werden können. Außerdem gibt es ein lokales Web-API im Stil des OpenAI-API, über das Anwendungen nahtlos auf die Modelle zugreifen können.Wichtig: LM Studio hostet selbst keine Modelle, sondern greift auf die Daten von Huggingface.co zu. Man könnte also sagen: Was GitHub für Code ist, ist Huggingface für KI-Modelle. Dort finden sich nicht nur Modelle zur Erstellung von Chatbots, sondern auch solche für Aufgaben wie Bild­erkennung oder -erzeugung, Audioverarbeitung und andere mehr. In LM Studio beschränkt man sich allerdings aktuell auf die Chatbot-Modelle.Um unser LLamaSharp-Beispiel auszuführen, suchen wir ein Modell über die Discover-Funktion in LM Studio aus, siehe Bild 1.
Auswahl eines KI-Modells über die „Discover“-Funktion in LM Studio (Bild 1) © Autor

Modellwahl

Wie in Bild 1 zu sehen ist, stehen uns weit mehr als nur ein Modell zur Verfügung. Aktuell gilt: „Große“ Modelle bewältigen deutlich komplexere Aufgaben als kleinere. Die LLM-Community bietet auf der Plattform LMArena.ai [4] eine Art Ranking für diese Modelle an, in dem verschiedene Leistungs­aspekte verglichen werden.Der derzeitige Spitzenreiter ist das Modell ChatGPT-4o. ­Allerdings ist es proprietär und aufgrund seiner enormen Größe für lokale Anwendungen ausgeschlossen.Ein guter Kompromiss – besonders für experimentelle Zwecke – ist das Modell „Phi 3.1 Mini 128k“ von Microsoft. Es ist mit einer Größe von 3,1 GByte relativ kompakt und kann daher problemlos in den Arbeitsspeicher der meisten aktuellen Systeme geladen werden.Das heruntergeladene Modell findet sich später unter dem Menüpunkt My Models wieder, siehe Bild 2. Von dort können wir den Dateipfad zum Modell herauskopieren und nun in un­sere Demoanwendung einfügen.
Heruntergeladene Modelle finden sich unter „My Models“ (Bild 2) © Autor

Demo mit Phi 3.1

Nachdem wir die Demo mit dem Phi-3.1-Modell gestartet haben, erhalten wir zunächst viele Informationen rund um das Modell. Anschließend kommt der „Assistent“ ins Spiel, und es ist möglich, mit ihm wie in Bild 3 gezeigt Nachrichten auszutauschen.
Nachrichtenaustausch mit dem Assistenten des Phi-3.1-Modells (Bild 3) © Autor

Mehr Wissen mit RAG

Sprachmodelle verfügen über ein grundlegendes Verständnis der Welt, jedoch fehlt ihnen oft Detailwissen. Besonders kleinere Modelle stoßen hier schnell an ihre Grenzen, aber auch größere Modelle wie ChatGPT benötigen zusätzliches „Domänenwissen“, um spezifische Themen abzudecken.Eine einfache Möglichkeit hierfür besteht wie in Bild 3 gezeigt darin, relevante Informationen als Chat-Nachricht in das Gespräch einzubringen. Das funktioniert gut für kleinere Textabschnitte, ist jedoch bei längeren Dokumenten kaum praktikabel. Hier kommt RAG (Retrieval-Augmented Generation) ins Spiel. Mit RAG kann ein Sprachmodell auf externe Datenquellen zugreifen und so Informationen dynamisch abrufen. LLamaSharp unterstützt RAG ebenfalls: mithilfe des Kernel-Memory-Projekts von Microsoft [5].

Überblick und Fazit

Wie bereits im Intro erwähnt, ist das Thema KI allgegenwärtig – und dabei äußerst umfangreich. LLamaSharp bietet hier eine elegante Lösung als Wrapper für das llama.cpp-Projekt und macht den Einstieg in die Arbeit mit KI für .NET-Ent­wicklerinnen und -Entwickler deutlich einfacher. Dank der Integration des Kernel-Memory-Projekts von Microsoft steht auch die Option zur Verfügung, Retrieval-Augmented Generation (RAG) [6] zu nutzen und somit dynamisch auf externe Datenquellen zuzugreifen.Für alle, die sich mit LLMs beschäftigen oder dies planen, ist LM Studio eine klare Empfehlung. Besonders für Anfänger, die noch nie von „GGUF“ oder „Huggingface“ gehört haben, stellt das Programm eine wertvolle Hilfe dar: Es vereinfacht den Download und das Testen von Sprachmodellen und überwindet so technische Hürden auf elegante Weise.

Alternativen zu LLamaSharp

Ein aktueller Trend in der Chatbot-Entwicklung ist die Verwendung des OpenAI-Web-API als De-facto-Standard. Das zeigt sich auch in den verfügbaren NuGet-Paketen: Mit Azure.AI.OpenAI und OpenAI lassen sich Anwendungen sowohl für den ChatGPT-Endpunkt als auch für den Azure-Dienst entwickeln, da beide denselben API-Standard nutzen. Inte­res­santerweise bieten auch andere KI-Dienste, wie etwa xAI, ein OpenAI-kompatibles API an. Ein weiteres Beispiel ist LM Studio, das ein lokales, Open­AI-kompatibles Web-API bereitstellt und somit einfache Tests ermöglicht. Und es gibt Olla­ma, ein Open-Source-Projekt, das die Funktionen von llama
.cpp über ein OpenAI-kompatibles API zugänglich macht.Der Vorteil dieser Kompatibilität liegt darin, dass ein Open­AI-API-Client flexibel zwischen verschiedenen Implemen­tierungen wechseln kann. LLamaSharp selbst bietet aktuell jedoch noch kein eigenes Web-API. Ein Nachteil der API-Nutzung ist der zusätzliche Bedarf an einem Server, der die Anfragen verarbeitet – dies kann jedoch auch zur Lastverteilung beitragen. In der LLamaSharp-Community gibt es Überlegungen für ein OpenAI-kompatibles Web-API (siehe Issue #269, [7]), wobei die Umsetzung aktuell noch offen ist.Zusammengefasst lässt sich sagen, dass LLamaSharp besonders gut in eine .NET-Umgebung passt. Wenn die Anwendung vollständig lokal ausgeführt werden soll, ist ein Umweg über ein WebAPI eher hinderlich. In anderen Konstellationen sollte jedoch geprüft werden, ob eine API-basierte Lösung sinnvoll ist.

Fussnoten

  1. llama.cpp bei GitHub, http://www.dotnetpro.de/SL2502LLama1
  2. LLamaSharp bei GitHub, http://www.dotnetpro.de/SL2502LLama2
  3. LLamaSharp, Using CUDA when both CPU and Cuda12 back-ends are present, #456, http://www.dotnetpro.de/SL2502LLama3
  4. Chatbot Arena LLM Leaderboard: Community-driven Evaluation for Best LLM and AI chatbots, https://lmarena.ai/?leaderboard
  5. kernel-memory bei GitHub, http://www.dotnetpro.de/SL2502LLama4
  6. Retrieval-augmented generation bei Wikipedia, http://www.dotnetpro.de/SL2502LLama5
  7. LLamaSharp, Create HTTP API server and provide API like OAI, #269, http://www.dotnetpro.de/SL2502LLama6

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Evolutionäres Prototyping von Business-Apps - Low Code/No Code und KI mit Power Apps
Microsoft baut Power Apps zunehmend mit Features aus, um die Low-Code-/No-Code-Welt mit der KI und der professionellen Programmierung zu verbinden.
19 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige