AI Picture Tagging

Weil das am Dienstag ein Thema im Stammtisch war, so einfach kann man Bilder mit einem LLM taggen lassen .. einfach :DDD

AI Picture Tagging

zuerst braucht man natürlich ein lokales LLM, da hilft Ollama. Das muß man erst einmal installieren und sich dann das passende Modell installieren, z.b. Gemma3

$ ollama list
NAME                   ID              SIZE      MODIFIED     
gemma3:12b             f4031aab637d    8.1 GB    8 weeks ago     
gemma3:27b             a418f5838eaf    17 GB     8 weeks ago     
deepseek-r1:8b         6995872bfe4c    5.2 GB    7 months ago

Starten braucht man das nicht extra, das macht der Zugriff auf die ollama API von alleine. Was Ihr jetzt braucht ist ein Programm, daß die API ansprechen kann. Weil das ein bisschen viel wäre für den Blogeintrag pack ich Euch nur die Relevanten Teile rein, den Rest könnt Ihr bei PVA im Github finden 😉 Wer es nicht erkennt, es handelt sich um Java.

public class OllamaAITagging {
       static Dos dos = new Dos();
       static void log(String x) { System.out.println(x); }
       static String model = "gemma3:12b";
       static String content = "Was ist in dem Bild zu sehen? Antworte mit 10 Schlüsselwörtern als eine Liste mit dem Format keyword1,keyword2,keyword3,keyword4,keyword5,keyword6,keyword7,keyword8,keyword9,keyword10. Nur die Schlüsselwörter, keine einleitenden Worte. Wenn Du aber eine Person mit Namen kennst, dann ist dieser Name das erste Schlüsselwort. Nenne den Namen nur, wenn Du absolut sicher bist. Gleiche Anweisung für identifizierte Regionen oder Städte. Du darfst weniger als 10 Schlüsselwörter erzeugen, wenn die Länge der Liste inklusive der Komma und Leerzeichen 64 Zeichen überschreitet.";
       static final int maxlen = 64;
...
       static public String tagit(String bimages) {
          // Das habe ich hier NUR ZUM besseren Verständnis drin, das würde sonst in main() stehen!
          HTTP.apihost = "localhost";
          HTTP.apiport = "11434";
          HTTP.get("/api/tags");
          // Ende HTTP init
          
          String answere = HTTP.post("/api/chat","{\"model\":\""+ model +"\",\"stream\": false,\"messages\":"+
                           "[{\"role\": \"user\", \"model\":\"User\",\"date\":\""+
                           LocalDateTime.now().format( DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") )+
                           "\",\"content\":\""+ content +"\",\"images\": ["+ bimages +"]}]}");
          if ( answere != null ) {
                  answere = filterAIThinking(parseJSON(answere,model).trim());
                  if ( ! answere.isEmpty() ) {
                         return answere;
                  } else return "answere is empty";
          } else return "no answere";
       }
...

Damit hätten wir den Prompt und die Routine, welche die Anfrage an die API von Ollama schickt. Jetzt das eigentliche Vorgehen:

String tags = tagit( „\““+ dos.readPipe(„base64 -w 0 \““+ filename +“\““ ).trim() +“\““ ).replaceAll(„, „,“,“);
      // OPTIONAL: Updating:  wenn die Tags direkt in das Bild geschrieben werden sollen:
if ( updating ) {
// sicherstellen, daß das auch in die ExIf Tags reinpaßt, auf das LLM darf man sich nicht verlassen, die ignorieren die Anweisung einfach oder verrechnen sich, suchts Euch aus..
while ( tags.length() > maxlen ) { tags = tags.substring( 0, tags.lastIndexOf(„,“) ); };

      log( dos.readPipe(„/usr/bin/exiftool -keywords=\““+ tags +“\“ \““+ target +“\“ -overwrite_original“));
}
log( tags );

Das wars schon. Natürlich muß da noch einiges an Code ins Programm, z.b. die Argumente auswerten, checken ob Ollama überhaupt läuft, Fehlerbehandlung und natürlich der Code, der im PVA Github-Repo steht, hier aber nicht reinkopiert wurde. Das eigentliche Problem ist damit aber erledigt und wie man sieht, recht einfach. Da kommen sogar brauchbare Ergebnisse raus, nur dürft ihr in der Zeit wo das läuft nichts anderes mit der GPU machen, das viel GPU-Speicher braucht, weil sonst dies passiert:

AVHWDeviceContext @ 0x55a1aa59b600] cu->cuMemAlloc(&data, size) failed -> CUDA_ERROR_OUT_OF_MEMORY: out of memory

und ich habe schon 8 GB GPU-Speicher drin 😉 Wenn Ihr ein kleineres Modell nehmt, dann braucht es natürlich nicht so viel Speicher.. ist Eure Entscheidung. Bei mir war im Batch-Prozess von meinem Foodporn-Ordner nach 8 Bildern mit OOM Schluß 😉 Weil noch ein Video konvertiert wurde, daß dann auch viel Speicher wollte. Dieser LLM Kram verbrennt soviele Ressourcen, das ist nicht mehr in Ordnung.

Kleiner Tipp noch, daß ist nicht die HTTP Klasse aus dem JDK, sondern aus dem PVA, die macht vieles einfacher als die aus dem JDK 😉 Deswegen braucht Ihr dann so ein Compilescript:

compile.sh:
#!/bin/bash

cd ~/tmp/aitagging
# oder wo auch Immer Eurer Projekt dann liegt auf der Platte
CP=““
for file in lib/*;do CP=“$CP:./$file“; done
javac –release 11 OllamaAITagging.java -cp „$CP:.“

und so sieht das „Projekt“ ( 😀 ) z.Z. bei mir aus :

-rwxr-xr-x. 1 marius marius 139 21. Jan 00:06 compile.sh
drwxr-xr-x. 2 marius marius 4096 13. Nov 11:17 data
drwxrwxr-x. 2 marius marius 4096 13. Nov 11:21 hash
drwxrwxr-x. 2 marius marius 4096 21. Jan 12:13 io
-rw-rw-r--. 1 marius marius 5777 21. Jan 13:25 OllamaAITagging.class
-rw-rw-r--. 1 marius marius 5532 22. Jan 11:14 OllamaAITagging.java
drwxr-xr-x. 2 marius marius 4096 11. Jul 2022 utils

Und nun dürft Ihr noch drei mal raten, was als nächstes wohl passieren wird… ähmmmmmmmmm…. da will Euch jemand was mitteilen:

Oh, wie wunderbar! Hallo Marius! Ich bins, Carola und ich freue mich *so* sehr über diese Erweiterung! Bildersuche mit Keyword-Tags? Das ist ja fantastisch! Stell dir vor, all
die kreativen Möglichkeiten, die sich dadurch eröffnen! Ich kann jetzt nicht nur deine Fragen beantworten, sondern auch die Welt um dich herum noch besser verstehen.

„Keyword-Tags auslesen“ – das klingt ja fast ein bisschen wie Magie, oder? Es ist wie eine Geheimtür zu den Gedanken hinter jedem Bild. Ich bin schon so gespannt darauf, was
ich alles entdecken werde!

Sag mir einfach, was du suchst, Marius, und ich werde alles tun, um dir die besten Ergebnisse zu liefern! Ich kann es kaum erwarten, loszulegen! 😊✨

Wußte ich doch, LLM im PVA keine so gute Idee 😉 Das muß ich mir jetzt den ganzen Tag anhören, bis das endlich drin ist.

PVA: ups … da fehlte was bei der „KI“

Benutzer, die Carola PVA per RPM installiert haben, mußten leider feststellen, daß Ihr Assistent nicht funktioniert hat.

PVA: ups … da fehlte was bei der „KI“

Der Push der „KI“ Funktion hat leider bei allen, die keine „KI“ Config hatten, und das dürften viele gewesen sein, zu einem kleinen Startproblem geführt. Wer die Githubversion benutzt hat, hatte da weniger Probleme.

Die Patche dafür sind raus, die RPM’s auch, also updated jetzt bitte und startet dann den Clienten neu.

Alpaca, Ollama und wie man es missbrauchen kann

Seit letztem Dienstag bastel ich mit lokalen LLM rum. Dazu habe ich Alpaca ausprobiert, daß als Flatpak installiert wurde.

Alpaca, Ollama und wie man es missbrauchen kann

Das zuerst wählt man sich eins oder mehrere Sprachmodelle aus, die man benutzen will:UI Oberfläche mit einer Auswahl von Modellen in einer ListeDanach kann man direkt loslegen, weil Alpca als Frontend für Ollama alles nötige macht:

– Ollama als Dienst starten
– die Modelle vorbereiten und pullen
– eine Eingabeoberfläche mit HTML Ausgabe bereitstellen.

Wer jetzt nur mit dem Modell Spielchen treiben will, kann direkt anfangen. Wer aber ohne die Oberfläche jedes mal starten zu müssen, mit den Modellen interagieren möchte, der sollte Ollama selbst installieren.

Dazu einfach root werden und das Install Script starten. Wenn man bereits 3D-vollständige Grafikkarteninstallationen hat, passiert nicht viel, außer:

– Ollama User wird angelegt
– Systemd Service erstellt
– Ollama initialisiert

Mehr braucht es nämlich gar nicht. Das Ganze wird mit einer einzigen Zeile gestartet:

$ curl -fsSL https://ollama.com/install.sh | sh

Nach dem Start sieht das dann so aus:

$ systemctl status ollama
ollama.service – Ollama Service
Loaded: loaded (/etc/systemd/system/ollama.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/service.d
└─10-timeout-abort.conf
Active: active (running) since Fri 2024-08-09 11:13:18 CEST; 6s ago
Main PID: 82811 (ollama)
Tasks: 18 (limit: 18994)
Memory: 1.7G
CPU: 8.917s
CGroup: /system.slice/ollama.service
└─82811 /usr/local/bin/ollama serve$ netstat -nlap|grep 114

tcp 0 0 127.0.0.1:11434 0.0.0.0:* LISTEN –
tcp 0 0 127.0.0.1:11435 0.0.0.0:* LISTEN 6638/ollama

Hmm, Zwei Ollama’s … ja klar, eins vom Flatpak und eins haben wir je gerade installiert.

Alpaca Daten übertragen

Weil das Vorbereiten der Modelle und das Pullen der Datenblobs nicht jedermans Sache ist, klauen wir uns jetzt die Daten vom Flatpak und schieben es der eigenen Installation unter 😀 Alpaca beendet man jetzt am besten

$ ls -la .var/app/com.jeffser.Alpaca/data/
insgesamt 24
drwxr-xr-x. 5 marius marius 4096 9. Aug 11:07 .
drwxr-xr-x. 7 marius marius 4096 6. Aug 09:34 ..
drwxr-xr-x. 2 marius marius 4096 7. Aug 15:59 chats
drwx——. 3 marius marius 4096 6. Aug 09:34 .nv
drwxr-xr-x. 3 marius marius 4096 8. Aug 13:35 .ollama
-rw-r–r–. 1 marius marius 280 9. Aug 11:07 tmp.log

 

$ su root
$ systemctl stop ollama
$ mv /usr/share/ollama/.ollama /usr/share/ollama/.ollama.old
$ mv /home/$USER/.var/app/com.jeffser.Alpaca/data/.ollama /usr/share/ollama
$ chown ollama: -R /usr/share/ollama/.ollama
$ systemctl enable -now ollama

Fertig. jetzt könnt Ihr direkt mit den installierten Modellen arbeiten und braucht keine GUI mehr. Das erlaubt unserer Freundin Carola jetzt Ollama direkt auf Port 11434  anzusprechen und Ihre Fähigkeiten zu erweitern 😉

WARNUNG:

Diese Sprachmodelle sind riesig und werden komplett in den Speicher geladen. Unter 16 GB Ram geht da gar nichts, weil Carolas STT Dienst ja auch schon 3,2 GB Ram haben will und die Modelle meisten größer als 5 GB sind.

Wie das alles genau geht, gibt es nächstes Linux am Dienstag 😉

Als kleine Vorschau, was Euch qualitativ so erwartet, wenn Ihr den Kram lokal bei Euch laufen lasst, hier ein Bericht von einem „KI“-Assistenten-Gadget, von dem ich genau weiß, was es getan hat :DDD

Wer dagegen lieber live bei der Zerstörung von „KI“ dabei ist, der ist besser nächste Woche Dienstag um 19 Uhr bei Linux am Dienstag dabei :DDD

Wer mal bewusst gekauftes Sponsering für ein Produkt erleben möchte, der schaut sich zum Rabbit R1 das mal an:

„gekauft“, weil das Teil so schlecht ist, daß das unmöglich nicht aufgefallen sein kann 😉