Einführung
Die von der GWDG bzw. KISSKI bereitgestellten Large-Language-Modelle (LLMs) können einerseits über die Weboberfläche Chat AI in der Academic Cloud genutzt werden (siehe GWDG Academic Cloud), andererseits aber auch per API (etwa für die Nutzung als Backend eigener Anwendungen oder z.B. im “Code Completion Service” CoCo der GWDG). Eine knappe Leistungsbeschreibung findet sich unter https://kisski.gwdg.de/leistungen/2-02-llm-service/.
Im Folgenden wird der API-Zugriff auf die GWDG-LLMs näher beschrieben bzw. anhand von Code-Beispielen demonstriert.
Zuteilung eines API keys
Ein API-Key der GWDG kann auf der oben angegebenen Startseite

durch Anklicken des Felds “Buchen” (Hervorhebung bei Mouse-Over) beantragt werden:
(für vollständige Ansicht anklicken)
Unter “Gewünschte Dienstleistung” stehen 4 Optionen zur Verfügung (wovon die erste inzwischen obsolet erscheint, vgl. GWDG Academic Cloud):
- Zugang zum Webinterface unseres Chatdienstes
- API Zugriff auf unseren Chatdienst
- RAG / finetuning
- Hosting Ihrer LLMs
wovon die zweite anzwählen ist. Es ist zu vermuten, dass bei “Kritische Daten in Bezug auf DSGVO oder ISO27001 werden verarbeitet” unbedingt das Nein-Feld anzukreuzen ist, da in den Nutzungsbedingungen die Verarbeitung personenbezogener Daten untersagt wird (was den Vorteil des datenschutzfreundlichen Hostings durch eine deutsche Behörde gegenüber ChatGPT & Co relativiert).
Nach Bearbeitung durch die GWDG erhält man Zugangsdaten per Email (in meinem vorabgesprochenen Fall am nächsten Vormittag mit Betreff “[SAIA] Your Chat AI API Key” von einer Mitarbeiterin der Uni Göttingen) samt Hinweisen auf verfügbare Modelle, Mailinglisten, monatliche Treffen und Vorschlägen für Test- bzw. Anwendungsmöglichkeiten.
Jeder GWDG API Key ist (derzeit) eine 33stellige Hexadezimalzahl, d.h. besteht aus Ziffern und den Buchstaben a-f (während OpenAI API keys immer mit “sk” beginnen, sehr viel länger sind und alle alphanumerischen Zeichen 0-9, A-Z, a-z enthalten können).
Nutzung der GWDG APIs
Abruf der Liste aller bereitgestellten Modelle
Unter der URL https://chat-ai.academiccloud.de/models kann die (offensichtlich dynamisch erzeugte) Liste der über GWDG-APIs nutzbaren Modelle im JSON-Format abgerufen werden. Aktuell (am 07.02.2025) werden folgende Daten geliefert:
| input | output | status | owned_by | name | demand | id | object | created |
|---|---|---|---|---|---|---|---|---|
| text | text | ready | chat-ai | Meta Llama 3.1 8B Instruct | 1 | meta-llama-3.1-8b-instruct | model | 1738965955 |
| text / image | text | ready | chat-ai | InternVL2.5 8B MPO | 0 | internvl2.5-8b | model | 1738965955 |
| text | text / thought | ready | chat-ai | DeepSeek R1 | 2 | deepseek-r1 | model | 1738965955 |
| text | text / thought | ready | chat-ai | DeepSeek R1 Distill Llama 70B | 1 | deepseek-r1-distill-llama-70b | model | 1738965955 |
| text | text | ready | chat-ai | Meta Llama 3.3 70B Instruct | 0 | llama-3.3-70b-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Llama 3.1 Nemotron 70B Instruct | 0 | llama-3.1-nemotron-70b-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Llama 3.1 SauerkrautLM 70B Instruct | 1 | llama-3.1-sauerkrautlm-70b-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Mistral Large Instruct | 1 | mistral-large-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Qwen 2.5 72B Instruct | 0 | qwen2.5-72b-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Qwen 2.5 Coder 32B Instruct | 0 | qwen2.5-coder-32b-instruct | model | 1738965955 |
| text | text | ready | chat-ai | Codestral 22B | 0 | codestral-22b | model | 1738965955 |
Dabei kann der Status (neben “ready”) u.a. auch den Wert “loading” annehmen. Die Spalte “demand” ist offenbar sehr neu und dürfte die aktuelle Nutzung wiederspiegeln. Die Einträge unter “created” geben den Zeitpunkt des Abrufs (als Unix time epoch) wieder, nicht etwa den Zeitpunkt der Installation. Für die Nutzung per API am wichtigsten sind sicherlich die “id”-Einträge (s.u.).
Obige Tabelle wurde übrigens per Online-Konverter auf https://jsontotable.org/ erzeugt; zuvor wurde das JSON-File durch das Kommando
awk '{print substr($0,9,length($0)-25)}' | sed -e 's/\[\"text\"\]/"text"/g' -e 's/\[\"text\",\"image\"\]/\"text \/ image\"/g' -e 's/\[\"text\",\"thought\"\]/\"text \/ thought\"/g'
bereinigt.
API-Tests auf der Kommandozeile
Abruf Modell-Liste mit cURL
Als einfachster Test bietet sich an, obige Liste der aktiven Modelle über die URL https://chat-ai.academiccloud.de/v1/models abzurufen (beachte das zusätzliche “/v1”), was eine Autorisierung verlangt. Ohne Autorisierung kommt im Browser die Antwort “Error No API key found in request. request_id: …”.
Auf der Kommandozeile (idealerweise Linux oder macOS) nutzen wir das Tool cURL. Ohne Autorisierung, d.h. durch Eingabe von
curl -X POST --url https://chat-ai.academiccloud.de/v1/models
würden wir eine der Browser-Fehlermeldung ähnliche Botschaft erhalten, etwa:
{
"message":"No API key found in request",
"request_id":"9a77bc55e2680330c62ec25dc979e90a"
}
Die gewünschte Liste erhält man dagegen (<GWDG_API_KEY> steht für den zugeteilten 33stelligen API key, der hier wegen dessen Vertraulichkeit nicht abgedruckt werden kann) mit
curl -X POST --url https://chat-ai.academiccloud.de/v1/models --header 'Authorization: Bearer <GWDG_API_KEY>'
Aktuell erscheint als Antwort (mit zur Erhöhung der Lesbarkeit eingefügten Zeilenumbrüchen)
{"data":[{"input":["text"],"output":["text"],"name":"Meta Llama 3.1 8B Instruct","status":"ready","owned_by":"chat-ai","id":"meta-llama-3.1-8b-instruct","object":"model","created":1738968458},
{"input":["text","image"],"output":["text"],"name":"InternVL2.5 8B MPO","status":"ready","owned_by":"chat-ai","id":"internvl2.5-8b","object":"model","created":1738968458},
{"input":["text"],"output":["text","thought"],"name":"DeepSeek R1","status":"ready","owned_by":"chat-ai","id":"deepseek-r1","object":"model","created":1738968458},
{"input":["text"],"output":["text","thought"],"name":"DeepSeek R1 Distill Llama 70B","status":"ready","owned_by":"chat-ai","id":"deepseek-r1-distill-llama-70b","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Meta Llama 3.3 70B Instruct","status":"ready","owned_by":"chat-ai","id":"llama-3.3-70b-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Llama 3.1 Nemotron 70B Instruct","status":"ready","owned_by":"chat-ai","id":"llama-3.1-nemotron-70b-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Llama 3.1 SauerkrautLM 70B Instruct","status":"ready","owned_by":"chat-ai","id":"llama-3.1-sauerkrautlm-70b-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Mistral Large Instruct","status":"ready","owned_by":"chat-ai","id":"mistral-large-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Qwen 2.5 72B Instruct","status":"ready","owned_by":"chat-ai","id":"qwen2.5-72b-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Qwen 2.5 Coder 32B Instruct","status":"ready","owned_by":"chat-ai","id":"qwen2.5-coder-32b-instruct","object":"model","created":1738968458},
{"input":["text"],"output":["text"],"name":"Codestral 22B","status":"ready","owned_by":"chat-ai","id":"codestral-22b","object":"model","created":1738968458}],"object":"list"}%
was der oben angegebenen Tabelle entsprechen sollte (abgesehen von fehlenden Demand-Einträgen und neueren Zeitstempeln). Bei Eingabe eines ungültigen Keys erscheint dagegen eine Meldung der Art
{
"message":"Unauthorized",
"request_id":"daf51d67202946737cd41d4b2cc1e40a"
}%
Speicherung des API Keys in einer Shell-Variable
Generell empfiehlt es sich, den API Key nicht manuell in jedes Shell-Kommando oder Skript einzutragen, sondern stattdessen Shell-Variablen zu verwenden. In der zsh oder bash lautet dafür der Befehl (wobei <GWDG_API_KEY> wieder durch den eigenen Key zu ersetzen ist):
export GWDG_API_KEY=<GWDG_API_KEY>
Im Folgenden werden wir annehmen, dass die Variable GWDG_API_KEY korrekt gesetzt wurde (was durch Angabe des Shell-Kommandos echo ${GWDG_API_KEY} überprüft werden kann).
Unter Verwendung der Variable lautet das oben verwendete Kommando zur Ausgabe der Liste aller Modelle:
curl -X POST --url https://chat-ai.academiccloud.de/v1/models --header 'Authorization: Bearer '${GWDG_API_KEY}
Erste LLM-Nutzung per API mit cURL: Textergänzung mit Llama
Als ersten echten Test der KI-Funktionalitäten greifen wir auf den Completions-Endpunkt der API zu und lassen ein kleineres Llama-Modell einen begonnenen Satz fortsetzen:
curl -i -X POST \
--url https://chat-ai.academiccloud.de/v1/completions \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '${GWDG_API_KEY}\
--header 'Content-Type: application/json'\
--data '{
"model": "meta-llama-3.1-8b-instruct",
"prompt": "San Francisco is a",
"max_tokens": 20,
"temperature": 0
}'
Bei der Ausführung erscheint eine recht lange Antwort:
HTTP/1.1 200 OK
Date: Fri, 07 Feb 2025 23:32:48 GMT
Server: uvicorn
Content-Type: application/json
X-RateLimit-Limit-Hour: 198
X-RateLimit-Limit-Day: 1000
X-RateLimit-Limit-Month: 2999
X-RateLimit-Remaining-Minute: 29
X-RateLimit-Remaining-Hour: 196
X-RateLimit-Remaining-Day: 970
X-RateLimit-Remaining-Month: 2969
RateLimit-Reset: 11
RateLimit-Remaining: 29
RateLimit-Limit: 30
X-RateLimit-Limit-Minute: 30
X-Kong-Upstream-Latency: 228
X-Kong-Proxy-Latency: 1
Via: kong/3.6.1
X-Kong-Request-Id: 81a37171fe80ad4220ddc644e068b56e
Access-Control-Allow-Origin: *
Transfer-Encoding: chunked
{"id":"cmpl-d64183e13b1f4414afd10356a7ed9621","object":"text_completion","created":1738971169,
"model":"meta-llama-3.1-8b-instruct","choices":[{"index":0,"text":
" city that is known for its vibrant arts and culture scene, and the San Francisco Museum of Modern Art",
"logprobs":null,"finish_reason":"length","stop_reason":null}],
"usage":{"prompt_tokens":4,"total_tokens":24,"completion_tokens":20}}%
Im oberen Teil werden etliche nutzerspezifische Metadaten ausgegeben. Im unteren Teil (Zeilenumbrücke zur Lesbarkeit ergänzt) steht die eigentliche Antwort als JSON-Objekt. Der Satzanfang “San Francisco is a” wird also durch " city that is known for its vibrant arts and culture scene, and the San Francisco Museum of Modern Art" fortgesetzt und bricht dann (ohne Punkt) ab, weil das eingestellte Limit von 20 Output-Tokens erreicht wurde. Wegen der eingestellten Temperatur 0 sollte das Ergebnis deterministisch, also (bei gleicher Modellversion) immer gleich sein. Bei höherer Temperatur (im Bereich 0-2) wird die Antwort variabler; bei T=1 wurden beispielsweise folgende Fortsetzungen ausgegeben:
San Francisco is a …
- great city, but it’s also a challenging place to start a business. Between the high cost of
- major hub for medicine and biotech, with companies like Genentech, Biogen, and A
- great place for many different types of visitors to feel at home. From historians and culture vultures
Da es sich um ein Instruct-Modell handelt, kann man durch Abwandlung des obigen Kommandos leicht eine Chatbot-Funktionalität realisieren. Dazu ergänzen wir einen passenden Prompt:
curl -i -X POST \
--url https://chat-ai.academiccloud.de/v1/completions \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '${GWDG_API_KEY}\
--header 'Content-Type: application/json'\
--data '{
"model": "meta-llama-3.1-8b-instruct",
"prompt": "You are a helpful assistant. What is a good recipe for chocolat cake? ",
"max_tokens": 200,
"temperature": 0.6
}'
Mit etwas Glück erhält man direkt ein Rezept (bzw. dessen Anfang - für ein ganzes Rezept müsste man das Token-Limit erhöhen). Allerdings zeigen sich schnell die Grenzen des doch recht kleinen Modells. Für eine reale Anwendung ersetzt man vielleicht besser den Modell-ID durch das eines größeren Modells, etwa llama-3.3-70b-instruct und erhält z.B. folgende Antwort (bei Token-Limit von 500, konvertiert mit sed -e "s/\\\n/|/g" | tr '|' '\n', Rendering des Markdowns durch Site-Generator):
LLM-Ausgabe von Llama 70B (zum Ausklappen anklicken)
I want it to make 12 servings.
Here’s a classic recipe for a moist and delicious chocolate cake that serves 12:
Ingredients:
For the cake:
* 2 ¾ cups all-purpose flour
* 1 ½ cups granulated sugar
* 2 teaspoons baking powder
* 1 teaspoon salt
* 1 cup unsweetened cocoa powder
* 1 cup whole milk, at room temperature
* 2 large eggs, at room temperature
* 1 teaspoon vanilla extract
For the frosting (optional):
* 1 cup unsalted butter, at room temperature
* 2 cups confectioners’ sugar
* 1 teaspoon vanilla extract
* 2 ounces high-quality dark chocolate, melted
Instructions:
- Preheat your oven to 350°F (180°C). Grease two 9-inch (23cm) round cake pans and line the bottoms with parchment paper.
- Prepare the cake: In a medium bowl, whisk together flour, sugar, baking powder, and salt.
- Make the cake batter: In a large mixing bowl, combine cocoa powder and milk. Stir until smooth. Add eggs one at a time, whisking well after each addition. Whisk in vanilla extract.
- Combine dry and wet ingredients: Gradually add the dry ingredients to the chocolate mixture, whisking until just combined.
- Divide the batter: Divide the batter evenly between the prepared pans.
- Bake the cakes: Bake for 30-35 minutes or until a toothpick inserted in the center comes out clean. Let the cakes cool in the pans for 10 minutes, then transfer them to a wire rack to cool completely.
- Make the frosting (if using): Beat the butter until creamy, then gradually add confectioners’ sugar, beating until smooth. Add vanilla extract and melted chocolate, and beat until combined.
- Assemble the cake: Once the cakes are completely cool, place one layer on a serving plate and spread a layer of frosting on top (if using). Place the second layer on top and frost the entire cake with the remaining frosting (if using).
Tips and Variations:
* To ensure the cake is moist, don’t overmix the batter, and make sure to use room temperature ingredients.
* If you want a stronger chocolate flavor, use more cocoa powder or add a teaspoon of instant
Vergleich mit API-Zugriff per cURL auf GPT-4o
Die für den Zugriff auf die GWDG-Modelle genutzte Schnittstelle ist ein Beispiel für eine REST API. Ganz analog lassen sich auch die Modelle von OpenAI nutzen; allerdings ist z.B. GPT-4o nur über den Chat-Endpunkt nutzbar und verlangt etwas andere Parameter. Obige Abfrage nach einem Schokoladenkuchen-Rezept kann folgendermaßen angepasst werden:
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer "${OPENAI_API_KEY} \
https://api.openai.com/v1/chat/completions -d \
'{
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "What is a good recipe for chocolat cake?"
}
]
}'
Falls in der Shell-Variable ein gültiger OpenAI-Key gespeichert ist (was einen OpenAI-Plattform-Account mit hinreichendem Guthaben voraussetzt, vgl. z.B. https://benjamincrozat.com/gpt-4o), erhält man eine Antwort, z.B. (wieder konvertiert mit sed -e "s/\\\n/|/g" | tr '|' '\n', teilweise Rendering des Markdowns durch Site-Generator):
LLM-Ausgabe von GPT-4o (zum Ausklappen anklicken)
Here’s a classic chocolate cake recipe that’s both delicious and relatively easy to make. This recipe yields a moist and rich chocolate cake that’s perfect for any occasion.
### Ingredients
#### For the Cake:
- 1 and 3/4 cups (220g) all-purpose flour
- 3/4 cup (65g) unsweetened cocoa powder
- 2 cups (400g) granulated sugar
- 1 and 1/2 teaspoons baking powder
- 1 and 1/2 teaspoons baking soda
- 1 teaspoon salt
- 2 large eggs
- 1 cup (240ml) whole milk
- 1/2 cup (120ml) vegetable oil or canola oil
- 2 teaspoons vanilla extract
- 1 cup (240ml) boiling water
#### For the Frosting:
- 1 cup (230g) unsalted butter, at room temperature
- 3 and 1/2 cups (440g) powdered sugar
- 1/2 cup (65g) unsweetened cocoa powder
- 1/2 teaspoon salt
- 2 teaspoons vanilla extract
- 1/4 cup (60ml) heavy cream
### Instructions
#### Make the Cake:
-
Prepare the Pans: Preheat your oven to 350°F (175°C). Grease two 9-inch round cake pans and line the bottoms with parchment paper. Grease the parchment paper as well.
-
Combine Dry Ingredients: In a large mixing bowl, whisk together the flour, cocoa powder, sugar, baking powder, baking soda, and salt.
-
Mix Wet Ingredients: Add the eggs, milk, vegetable oil, and vanilla extract to the dry ingredients. Beat on medium speed with an electric mixer until well combined.
-
Add Boiling Water: Carefully stir in the boiling water. The batter will be quite thin, but this is expected.
-
Bake the Cake: Divide the batter evenly between the prepared cake pans. Bake for 30 to 35 minutes, or until a toothpick inserted in the center comes out clean.
-
Cool: Allow the cakes to cool in the pans for about 10 minutes, then remove them from the pans and transfer to a wire rack to cool completely.
#### Make the Frosting:
-
Beat the Butter: In a large bowl, beat the butter with an electric mixer on medium speed until creamy, about 2 minutes.
-
Add Dry Ingredients: Gradually add the powdered sugar and cocoa powder, beating on low speed until combined.
-
Add Vanilla and Cream: Add the salt, vanilla extract, and heavy cream. Increase the speed to medium-high and beat for another 3 minutes until light and fluffy. Adjust the consistency if necessary by adding more cream or powdered sugar.
#### Assemble the Cake:
-
Layer the Cake: Place one cake layer on a serving plate or cake stand. Spread about 1 cup of frosting on top. Add the second cake layer.
-
Frost the Cake: Use the remaining frosting to cover the top and sides of the cake. Smooth it out with a spatula or create decorative swirls if desired.
-
Serve: Enjoy your homemade chocolate cake! You can serve it as is, or with a scoop of ice cream or a dollop of whipped cream.
This cake should be stored in an airtight container at room temperature for a couple of days, or it can be kept in the refrigerator for up to a week. Enjoy!
Applikation: Bildanalyse per Python-Skript
Kommen wir jetzt zu einer recht coolen Applikation auf der Kommandozeile: Bildanalyse. Konkret verwenden wir einen als File test-image.png gespeicherten Screenshot:

Zur Verarbeitung wurde ein auf https://docs.hpc.gwdg.de/services/saia/index.html bereitgestellter Python-Beispielcode leicht modifiziert (mit Auslesen des API Keys aus einer Shell-Variable) im File analyze_image.py gespeichert, das hier wiedergegeben ist:
# File analyze_image.py
# Quelle: https://docs.hpc.gwdg.de/services/saia/index.html
import base64
from openai import OpenAI
from os import environ
# API configuration
api_key = environ['GWDG_API_KEY']
base_url = "https://chat-ai.academiccloud.de/v1"
model = "internvl2.5-8b" # Choose any available model
# Start OpenAI client
client = OpenAI(
api_key = api_key,
base_url = base_url,
)
# Function to encode the image
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
# Path to your image
image_path = "test-image.png"
# Getting the base64 string
base64_image = encode_image(image_path)
response = client.chat.completions.create(
model = model,
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is in this image?",
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
},
},
],
}
],
)
print(response.choices[0])
Der Code schickt die Frage (“What is in this image?”) sowie das Bild in einer für das LLM verständlichen Kodierung samt ergänzender Metadaten (Modellspezifikationen etc.) an den API-Endpunkt und gibt die Antwort aus, nachdem diese vom Endpunkt zurückgeliefert wurde. Voraussetzung für die Nutzung ist natürlich, dass lokal eine Umgebung für die Programmiersprache Python zur Verfügung steht. Auch müssen die benötigten Module ggf. noch installiert werden (z.B. mit pip install openai).
Beim ersten Aufruf (am 04.02.2025) lieferte das Kommando python analyze_image.py folgende Ausgabe (Zeilenumbrüche für Lesbarkeit eingefügt)
% python analyze_image.py
Choice(finish_reason='stop', index=0, message=ChatCompletionMessage(content="This image depicts a webpage from
Katholische Universität Eichstätt-Ingolstadt (KU). The page is discussing the university's internationalization
audit conducted by German Rectors' Conference experts. It includes images of students examining a globe,
symbolizing global education and collaboration. The content highlights that the university is assessing
its international standards and improving its strategy based on the review process.", role='assistant',
function_call=None, tool_calls=[]), logprobs=None, stop_reason=92542)
Das erscheint als beeindruckend gute knappe Analyse.
Am 08.02.2025 erzeugte das gleiche Kommando einen viel längeren Output, der kodierte Zeilenumbrüche und Markdown enthält und daher hier konvertiert (und wegen der Länge ausklappbar) dargestellt wird:
Ausgabe des Python-Skripts analyze_image.py (zum Ausklappen anklicken)
This image is a screenshot of a webpage from Katholische Universität Eichstätt-Ingolstadt with the headline “KU undergohes internationalization48 audit of German Reactors' Conference”.
Overall, the image conveys the following information according to the textual content visible:
- Title: The title suggests this running through an international audit process as provided by German Rectors' Conference.
- Interface and Elements: The image shows various navigation options like 'The KU', 'Study at the KU', 'Research' faintly visible.
- Main Image: It depicts four people, possibly students, holding a globe suggesting an international / academic context.
- Text Snippet: References the university's self-assessment as part of an audit, with experts confirming positive areas and suggesting further strategies for improvement in terms of internationalization activities.
Key textual elements explain topics like:
- Extensive development of a university-wide international strategy.
- Review and feedback on current position.
-–
Detailed Breakdown:
- URL: the link points to internationalization information specific to this university.
- Header:
- Displays the university's name and an image of the globe, implying global involvement.
- Navigation:
- Contains links such as The KU, Study, Research.
- Additional links appear concerning aspects like Internationalization, Transfer, Campus Life.
- Main Content:
- Discusses self-report evaluation by the university followed by external experts—presenting both strengths and areas for development.
- Mentions the German Rectors' Conference and activities in internationalization.
- Graphics:
- Four individuals holding a globe.
- Posture and clothing indicate university setting (possibly degrees or academic attire).
It also hints at the article's ongoing date or publication (“01-30-2025”).
### Summary:
- Visible text states structured assessment of the university's internationalization.
- Implies positive expert feedback indicating responsible progress in international academic activities.
- Provides insight into university-wide strategies for international development.
Diesmal wird die ganze Seite analysiert (was einer umfassenderen Interpretation von “image” entspricht). Erstaunlicherweise wird die URL mit Rechtschreibfehlern ausgegeben. Ansonsten erscheint die Analyse weitgehend zutreffend.
Offensichtlich ist es unpraktisch, wenn man sich die eigentlich interessierenden Antworten aus einem Wust von Metadaten und JSON-Konstrukten heraussuchen muss. Dafür könnte man einerseits das Programm erweitern oder Kommandozeilen-Skripte basteln. Andererseits existieren etablierte Frontends, die schon passende Routinen bereitstellen - wie etwa Gradio.
LLM-Nutzung per GWDG-API mit dem Web-Frontend Gradio
Mit folgendem Code lassen sich die GWDG-LLMs in einer Chat-GPT-ähnlichen Oberfläche nutzen:
# File demo_Gradio_GWDG-API.py
# Demo program using Gradio and the GWDG API for access to an LLM
import gradio as gr
from openai import OpenAI
from os import environ
client = OpenAI(
base_url="https://chat-ai.academiccloud.de/v1/",
api_key=environ['GWDG_API_KEY'],
)
def predict(message, history):
history.append({"role": "user", "content": message})
stream = client.chat.completions.create(messages=history, model="meta-llama-3.1-70b-instruct", stream=True)
chunks = []
for chunk in stream:
# Check if the chunk has any choices before accessing index 0
if chunk.choices and len(chunk.choices) > 0:
# Sometimes delta or content might be None, so use a default value
delta = chunk.choices[0].delta
content = getattr(delta, "content", "") if delta else ""
chunks.append(content)
else:
# Optionally log or handle the case where choices is empty
print("Received a chunk with no choices:", chunk)
yield "".join(chunks)
demo = gr.ChatInterface(predict, type="messages")
demo.launch()
Nach Ausführen von python demo_Gradio_GWDG-API.py erscheint auf der Kommandozeile ein Hinweis, unter welcher URL der (lokal laufende) Frontend-Server zu erreichen ist, etwa
% python demo_Gradio_GWDG-API.py
Running on local URL: http://127.0.0.1:7860
Ein Aufruf dieser URL mit dem Browser (hier mit Chrome - Achtung: Safari auf macOS hatte im Test Darstellungsfehler) liefert eine Seite mit Ausgabefenster, mehreren Schaltflächen und einem Eingabefenster (hier schon vorbefüllt):

Nach Anklicken des “Submit”-Buttons sollte sich (bei gültigem in der Shell-Variable GWDG_API_KEY gespeichertem API Key, s.o.) langsam eine Antwort aufbauen, etwa wie hier:

Das Gradio-Frontend hat die Nutzdaten aus dem von der GWDG-API gelieferten JSON-Output schön formatiert (inklusive Syntax Highlighting). Bei Bedarf können wir die einzelnen Kommandozeilenbefehle (jeweils mit Copy-Button rechts) oder den ganzen Dialog (durch Selektieren) leicht herauskopieren und an geeigneter Stelle einfügen (Frage manuell in Italics gesetzt, Code wurde von Typora automatisch erkannt und passend gesetzt):
What is Gradio and how can I install it?
Gradio is an open-source Python library that allows you to create and share machine learning models and other Python functions as web applications with a simple and intuitive interface. It’s particularly useful for data scientists and researchers to share their work and get feedback without requiring the users to have technical expertise.
To install Gradio, you can use pip:
pip install gradio
Alternatively, if you want to install the latest version of Gradio from the GitHub repository, you can use the following command:
pip install git+https://github.com/gradio-app/gradio.git
Mit Llama 70B kann man übrigens (im Gegensatz zu einigen kleinen Modellen) auch gut auf Deutsch kommunizieren, wie hier mit einem anderen Beispiel demostriert werden soll (wieder aus dem Gradio-Fenster kopiert):
Was kann man tun, um die Demokratie zu schützen?
Um die Demokratie zu schützen, gibt es mehrere Maßnahmen, die Sie ergreifen können:
- Informiert bleiben: Bleiben Sie auf dem Laufenden über politische Ereignisse und Entwicklungen in Ihrem Land und weltweit. Lesen Sie verschiedene Quellen und recherchieren Sie kritisch.
- Engagieren Sie sich: Nehmen Sie an Wahlen teil, unterstützen Sie politische Organisationen oder Initiativen, die Ihre Werte teilen, und engagieren Sie sich in Ihrem lokalen Gemeindeleben.
- Kritisches Denken: Üben Sie kritisches Denken und hinterfragen Sie Informationen, die Ihnen präsentiert werden. Seien Sie vorsichtig bei Falschinformationen und Desinformationen.
- Respekt für Minderheiten: Respektieren Sie die Rechte und Freiheiten von Minderheiten und unterstützen Sie ihre Teilhabe an der Gesellschaft.
- Transparenz und Rechenschaftspflicht: Fordern Sie Transparenz und Rechenschaftspflicht von Ihren politischen Vertretern und Institutionen ein.
- Bildung und Aufklärung: Unterstützen Sie Bildungsinitiativen, die Menschen über die Grundlagen der Demokratie und die Bedeutung von Bürgerrechten aufklären.
- Zivilgesellschaft stärken: Unterstützen Sie zivilgesellschaftliche Organisationen, die sich für Menschenrechte, Rechtsstaatlichkeit und die Stärkung der Demokratie einsetzen.
- Medienpluralismus: Unterstützen Sie unabhängige Medien und fördern Sie den Medienpluralismus, um sicherzustellen, dass verschiedene Stimmen und Perspektiven gehört werden.
Indem Sie diese Maßnahmen ergreifen, können Sie dazu beitragen, die Demokratie zu schützen und zu stärken.
GWDG CoCo AI - Code Completion in VS Code
Wie auf https://docs.hpc.gwdg.de/services/coco/ dokumentiert, können die GWDG-LLMs, insb. Codestral, direkt in der kostenlos durch Microsoft bereitgestellten Entwicklungsumgebung Visual Studio Code (vgl. Wikipedia-Artikel) zur Code-Analyse und zur automatischen Vervollständigung (autocomplete) verwendet werden.
Folgende Voraussetzungen müssen erfüllt werden:
- Erfolgreiche Installation von VS Code (Download-Button auf https://code.visualstudio.com anklicken und Instruktionen folgen)
- Installation der Extension Continue (Extension-Button in Sidebar anklicken, nach “Continue” suchen und installieren)
- Anpassung der Continue-Konfiguration mit Hinterlegung eines gültigen GWDG-API-Keys
Bei der Installation von Continue sollte im Heimatverzeichnis (~) des aktiven Benutzers ein verstecktes Unterverzeichnis .continue angelegt worden sein (unter macOS oder Linux z.B. per ls -al ~ sichtbar), in dem sich das Konfigurations-File config.json befindet. Dieses muss angepasst werden. Da ich die Anleitung auf https://docs.hpc.gwdg.de/services/coco/ nicht auf Anhieb verstanden habe (was bedeutet “write/replace the following attributes” genau?) und sie auch nicht ganz vollständig erscheint, hier ein erfolgreich getestetes vollständiges Konfigurations-File ~/.continue/config.json:
{
"models": [
{
"title": "Meta Llama 3 8B Instruct",
"model": "meta-llama-3-8b-instruct",
"apiBase": "https://chat-ai.academiccloud.de/v1",
"completionOptions": {},
"provider": "openai",
"apiKey": "<GWDG_API_KEY>"
},
{
"title": "Meta Llama 3 70B Instruct",
"model": "meta-llama-3-70b-instruct",
"apiBase": "https://chat-ai.academiccloud.de/v1",
"completionOptions": {},
"provider": "openai",
"apiKey": "<GWDG_API_KEY>"
},
{
"title": "Codestral-22B",
"model": "codestral-22b",
"apiBase": "https://chat-ai.academiccloud.de/v1",
"completionOptions": {
"temperature": 0.2,
"topP": 0.1
},
"provider": "openai",
"apiKey": "<GWDG_API_KEY>"
},
{
"model": "gpt-4o",
"title": "GPT-4o",
"systemMessage": "You are an expert software developer. You give helpful and concise responses.",
"apiKey": "<OPENAI_API_KEY>",
"provider": "openai"
}
],
"tabAutocompleteModel": {
"title": "Tab Autocomplete",
"model": "codestral-22b",
"apiBase": "https://chat-ai.academiccloud.de/v1",
"completionOptions": {
"temperature": 0.2,
"topP": 0.1
},
"provider": "openai",
"apiKey": "<GWDG_API_KEY>"
},
"contextProviders": [
{
"name": "code",
"params": {}
},
{
"name": "docs",
"params": {}
},
{
"name": "diff",
"params": {}
},
{
"name": "terminal",
"params": {}
},
{
"name": "problems",
"params": {}
},
{
"name": "folder",
"params": {}
},
{
"name": "codebase",
"params": {}
}
],
"slashCommands": [
{
"name": "share",
"description": "Export the current chat session to markdown"
},
{
"name": "cmd",
"description": "Generate a shell command"
},
{
"name": "commit",
"description": "Generate a git commit message"
}
],
"embeddingsProvider": {
"provider": "free-trial"
},
"reranker": {
"name": "free-trial"
}
}
Dabei wurden die enthaltenen API-Keys jeweils durch Platzhalter ersetzt. Neben den GWDG-LLMs ist auch GPT-4o eingetragen, dessen Nutzung per API ein Guthaben bei OpenAI voraussetzt (siehe oben).
Als (relativ minimalistisches) Beispiel wird die Erweiterung auf den oben für Bildanalyse genutzten Python-Code angewendet:

Hier wurde im geöffneten Code-Fenster die Funktionsdefinition von encode_image markiert; nach dem Kommando ⌘-L (bzw. Ctrl-L auf Windows/Linux) öffnete sich eine Continue-Sidebar mit einer Kopie des Textes. Nach Auswahl von “Codestral-22B” und Eingabe der Frage “What does this code do?” erschien dann die gezeigte Erklärung. Unterhalb lässt sich der Dialog fortsetzen.
Dank dem Eintrag als tabAutocompleteModel kann Codestral auch direkt im Code-Fenster Fortsetzungen vorschlagen (etwa aufgrund von hinreichend spezifischen Kommentaren oder bei unvollständigem Code); Vorschläge sollten sich an passenden Stellen durch Drücken der Tab-Taste abrufen (und durch <Return> akzeptieren) lassen. Weitere Infos siehe https://docs.hpc.gwdg.de/services/coco/ bzw. Continue documentation.