Entwicklung & Code
GPT-OSS: Einblick in die offenen Modelle von OpenAI
Das lange Warten auf das erste OpenAI-Modell mit offenen Gewichten hat ein Ende: OpenAI hat am 5. August GPT-OSS veröffentlicht. Bei genauerer Betrachtung zeigt sich: Das Warten hat sich gelohnt. Das Modell funktioniert hervorragend und enthält viele Innovationen. Außerdem steht es unter der sehr liberalen Apache-2.0-Lizenz zur Verfügung.
Prof. Dr. Christian Winkler beschäftigt sich speziell mit der automatisierten Analyse natürlichsprachiger Texte (NLP). Als Professor an der TH Nürnberg konzentriert er sich bei seiner Forschung auf die Optimierung der User Experience.
Architektur der Modelle
Eigentlich hat OpenAI nicht ein Modell, sondern gleich zwei veröffentlicht. Neben dem großen Modell 120B mit 117 Milliarden Parametern gibt es auch noch ein kleines 20B-Modell mit 21 Milliarden Parametern.
Beide Modelle nutzen die Mixture-of-Experts-Architektur und benötigen damit in der Inferenzphase deutlich weniger aktive Parameter, die in die Berechnung eingehen. Besonders ausgeprägt ist das beim großen Modell, das lediglich vier seiner 128 Experten gleichzeitig nutzt. Dadurch gibt es zwischen den beiden Modellen keinen großen Unterschied bei der Zahl der aktiven Parameter. Das kleinere Modell ist daher nicht viel schneller, benötigt aber deutlich weniger Arbeitsspeicher (dazu später mehr).
Modell | GPT-OSS-120B | GPT-OSS-20B |
Anzahl Parameter | 117 Milliarden | 21 Milliarden |
Anzahl aktive Parameter | 5,1 Milliarden | 3,6 Milliarden |
Anzahl Layer | 36 | 24 |
Anzahl Experten | 128 | 32 |
Anzahl aktive Experten | 4 | 4 |
Anzahl Attention Heads | 64 | 64 |
Interessant ist die Architektur der Layer: OpenAI verwendet abwechselnd eine volle Attention, also den Blick auf den gesamten Inhalt, und eine mit dem sogenannten Sliding Window, bei dem es die Inhalte in kleinere, überlappende Segmente aufteilt. Diese Variante benötigt deutlich weniger Speicher und Rechenzeit, kann aber weniger gut mit langen Kontexten umgehen. Das gleicht die volle Attention in den jeweils dazwischenliegenden Layern aus.
Weniger Speicherbedarf, flexibleres Reasoning
Auf der Model Card bei Hugging Face steht, dass das große Modell auf einer H100-GPU ausführbar ist. Das ist zunächst erstaunlich, denn 121 Milliarden Parameter sind selbst im von DeepSeek verwendeten sparsamen FP8-Format (8-bit Floating Point) zu groß. Allerdings hat OpenAI noch weiter gespart und die Gewichte im noch kompakteren MXFP4-Format (Microscaling 4-bit Floating Point) veröffentlicht, das nur halb so viel Speicher benötigt. Damit erfordert das Modell nur 60 GByte RAM für die Gewichte. Der Nachteil dabei ist, dass nur die in H100- oder RTX 5090-Karten verwendeten Hopper-GPUs von Nvidia mit diesem Format effizient rechnen können.
Auf GPUs der älteren Generation laufen die Modelle zwar, brauchen aber viermal so viel Speicher. Ein Schelm, der dabei an Cross-Sponsoring mit Nvidia denkt. Bemerkenswert ist dennoch, dass sich innerhalb nur eines Jahres das etablierte bfloat16-Format jetzt (zumindest bei diesen Modellen) auf vier Bit verkürzt hat und damit nur noch ein Viertel des Speicherplatzes notwendig ist.
OpenAI erlaubt außerdem, das Reasoning der GPT-OSS-Modelle zu konfigurieren. Man kann also festlegen, wie ausführlich die Modelle ihre Gedanken exponieren sollen. Das ist äußerst nützlich, weil manche Modelle im Reasoning-Mode zu geschwätzig sind und eine Menge Token erzeugen. Man muss also nicht nur lange Ausführungen lesen und auf das Generieren warten, sondern auch für viele Token zahlen. Wie gut diese Einstellung wirklich funktioniert, muss die Praxis zeigen.
Das neue Harmony Response Format
Bei den hybriden Qwen3-Modellen von Alibaba lässt sich durch die Angabe von /no_think
im Prompt das Reasoning ausschalten, was wenig flexibel ist. Hier hat sich OpenAI mehr Gedanken gemacht und gleich ein neues Chatformat definiert: Das Harmony Response Format ist sehr viel flexibler als alle bisherigen Chat-Templates und lässt viele Möglichkeiten der Interaktion mit den Modellen zu.
Bei näherer Betrachtung ist es fast erstaunlich, dass man so lange an den – jetzt überkommen erscheinenden – Chat-Templates festgehalten hat. Spannend ist, dass sich beim Ausprobieren des Harmony-Codes der Knowledge Cut-off von GPT-OSS im Juni 2024 findet, die jüngsten Trainingsdaten für das Modell also über ein Jahr alt sind. Dass es für Harmony auch Rust-Code gibt, könnte ein Hinweis darauf sein, dass OpenAI intern mit der Programmiersprache arbeitet, um die Effizienz der Software zu erhöhen.
Harmony ist ein deutlich flexibleres Format als die bisherigen Chat-Templates. Es erlaubt mehr Meta-Instruktionen und sogenannte Channels, die das Modell auch bei der Antwort berücksichtigt. Bei allen Vorteilen hat Harmony aber auch einen Nachteil: Durch das Verarbeiten der zusätzlichen Bereiche wie Regeln und Channels produziert das System viele Token. Die dadurch verringerte Effizienz kann auch ein abgemildertes Reasoning nicht kompensieren.
(Bild: Sikorka/Shutterstock)
Die Online-Konferenz LLMs im Unternehmen am 29. Oktober zeigt, wie man das passende Modell auswählt, die Infrastruktur aufbaut und die Sicherheit im Griff behält. Außerdem gibt der Thementag von iX und dpunkt.verlag einen Ausblick auf Liquid Foundation Models als nächste Generation von LLMs.
GPT-OSS ist ein agentisches Modell, das Funktionen aufrufen kann. OpenAI geht dabei noch einen Schritt weiter und erlaubt neuerdings das Browsen im Web. Anbieter wie Anthropic ermöglichen jedoch schon länger, mit ihren Modellen den Browser zu steuern, und Perplexity bietet sogar einen eigenen Browser an. GPT-OSS ermöglicht es außerdem, Python-Code auszuführen. Wie weit man dem generierten Code vertrauen kann, lässt sich auf Anhieb nicht gesichert sagen.
Über Details des Trainingsprozesses schweigt OpenAI sich ebenso aus wie über die dafür verwendeten Daten. Hier kocht jeder vermutlich sein eigenes Süppchen, auch die chinesischen Modellanbieter hüllen sich dazu in Schweigen. Nur für Olmo vom Allen AI Institute und SmolLM von Hugging Face sind wirklich alle Details veröffentlicht.
Entwicklung & Code
Event-Driven, Teil 7: Wie man mit Event-getriebener Architektur anfängt
Event-getriebene Architektur klingt zunächst nach einem radikalen Paradigmenwechsel – und das ist sie auch. Doch gerade weil sie auf einer anderen Denkweise beruht, ist der Einstieg oft einfacher, als viele glauben. Entscheidend ist, dass man nicht mit der Technik beginnt, sondern mit dem gemeinsamen Verständnis.
Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.
Dieser letzte Teil der Serie zeigt, wie man ein solches System in der Praxis aufbaut, welche typischen Stolperfallen man dabei vermeiden sollte und wie man Event-getriebene Architektur schrittweise einführen kann.
Reden ist wichtiger als Code
Am Anfang steht kein Code, kein Framework, keine Datenbank – sondern ein Gespräch. Wer Event-getriebene Systeme bauen will, muss zuerst verstehen, was in der Domäne passiert. Und das gelingt am besten im Dialog mit den Menschen, die diese Domäne kennen: den Fachexpertinnen und -experten.
Ein erster Schritt kann sein, gemeinsam Ereignisse zu sammeln: Was passiert in eurem Tagesgeschäft? Welche Abläufe gibt es? Welche Entscheidungen werden getroffen? Was ist wichtig, was ist selten, was ist kritisch?
Dabei hilft es, ganz bewusst in der Sprache der Fachlichkeit zu bleiben – ohne technische Begriffe, ohne JSON-Formate, ohne Implementierungsdetails.
Event Storming und ähnliche Methoden
Bewährt haben sich dabei Formate wie Event Storming: Man klebt Events als Post-Its an eine Wand, ordnet sie zeitlich und diskutiert darüber. So entstehen Schritt für Schritt die zentralen Abläufe der Domäne – verständlich, diskutierbar und überprüfbar.
In dieser Phase ist es wichtig, die Sprache ernst zu nehmen: Ein Event wie „Bestellung wurde storniert“ muss nicht nur technisch korrekt sein, sondern es muss auch inhaltlich passen. Und vor allem: Es muss für alle Beteiligten dasselbe bedeuten.
Nicht das ganze System umstellen
Ein häufiger Fehler ist, Event-getriebene Architektur gleich auf das gesamte System anwenden zu wollen. Das führt oft zu Überforderung – fachlich, organisatorisch und technisch.
Besser ist es, sich ein isoliertes Teilproblem zu suchen – einen Prozess, der in sich geschlossen ist, aber bereits von klassischen Architekturen überfordert wirkt.
Typisch sind:
- Benachrichtigungsprozesse
- Abrechnungs- oder Mahnwesen
- Genehmigungsworkflows
- Integration mit Drittsystemen
Hier lässt sich Event-getriebene Architektur gut einführen, zunächst als ergänzender Ansatz, nicht als Ersatz für das bestehende System.
Nicht die Technik überfrachten
Viele Einsteiger verlieren sich schnell in technischen Entscheidungen: Welches Event-Format soll man wählen? Welche Queue verwenden? Wie Event-Versionierung lösen?
Diese Fragen sind wichtig, aber nicht am Anfang. Wer Events als fachliche Beschreibung ernst nimmt, kann diese zunächst einfach als strukturierte Objekte behandeln – selbst ohne Event-Store oder Queue. Die technische Infrastruktur lässt sich nach und nach ergänzen.
Erst wenn klar ist, welche Events entstehen, wann sie entstehen und was sie bedeuten, lohnt es sich, über Serialisierung, Partitionierung und Replikation nachzudenken.
Was sich langfristig verändert
Wer einmal damit beginnt, in Events zu denken, verändert die eigene Sicht auf Systeme dauerhaft. Man beginnt, Abläufe nicht mehr als Abfolge von Methodenaufrufen zu sehen, sondern als Geschichte von Ereignissen. Und das hat viele positive Effekte:
- Die Kommunikation mit dem Fachbereich wird klarer.
- Die Modelle werden stabiler.
- Die Systeme werden flexibler und nachvollziehbarer.
- Neue Anforderungen lassen sich oft mit vorhandenen Events umsetzen.
Fazit und Ausblick
Event-getriebene Architektur ist kein Selbstzweck – und keine technische Mode. Sie ist eine Antwort auf Systeme, die zu unübersichtlich, zu gekoppelt und zu schwer veränderbar geworden sind. Wer Systeme baut, die sich natürlich weiterentwickeln lassen sollen, findet in Events ein kraftvolles Werkzeug.
Diese Serie hat den Bogen gespannt – von den Grenzen klassischer Architektur über die Bausteine, Denkweisen und Fallstricke bis hin zum konkreten Einstieg. Wer den nächsten Schritt gehen möchte, findet auf cqrs.com weitere Ressourcen, konkrete Beispiele und vertiefende Konzepte.
(mai)
Entwicklung & Code
Sourcecode-Editor: Visual Studio Code 1.103 bringt Support für GPT-5
Microsoft hat das Juli-Update seines freien Sourcecode-Editors Visual Studio Code 1.103 veröffentlicht. In dieser Version kann er bereits in Form einer öffentlichen Preview die Features von OpenAIs frisch erschienenem Sprachmodell GPT-5 nutzen. Zudem können Entwicklerinnen und Entwickler nun im Chat Checkpoints setzen, um zu einem früheren Zustand zurückzukehren.
GPT-5 jetzt als Preview in GitHub Copilot
Als fortschrittlichstes Sprachmodell von OpenAI soll GPT-5 Updates für mehrere Bereiche bringen, die für Developer relevant sind: GPT-5 soll sowohl das Reasoning als auch das Coding und den Chat verbessern.
Der GPT-5-Support läuft derzeit als Public Preview für GitHub Copilot und wird allen zahlenden Copilot-Kundinnen und -Kunden zur Verfügung gestellt – nicht nur in Visual Studio Code, sondern auch auf github.com im GitHub Copilot Chat und in der mobilen Version GitHub Mobile. Um darauf in VS Code zuzugreifen, wählen Entwicklerinnen und Entwickler GPT-5 innerhalb der Chat View im Model Picker aus.
Die öffentliche Preview für OpenAI GPT-5 steht in VS Code bereit.
(Bild: GitHub-Blog)
Admins von Copilot Enterprise und Business müssen den GPT-5-Support zunächst in den Copilot-Einstellungen erlauben. Dann können User innerhalb der Organisation in VS Code das neue Sprachmodell auswählen.
Als eine weitere Neuerung im Chat lassen sich nun Checkpoints nutzen, um zu einem früheren Chat-Status zurückzukehren und Änderungen rückgängig zu machen. Wie Microsoft ausführt, soll das insbesondere beim Bearbeiten mehrerer Dateien innerhalb einer Chat-Session hilfreich sein. Auch das Wiederherstellen zu einem Checkpoint lässt sich dabei rückgängig machen.
Die neue Funktion Checkpoints kann den Chat in VS Code auf einen bestimmten Status zurücksetzen.
(Bild: Microsoft)
Checkpoints sind standardmäßig aktiviert und lassen sich mit der Einstellung chat.checkpoints.enabled
steuern.
(Bild: Golden Sikorka/Shutterstock)
Die Online-Konferenz LLMs im Unternehmen am 29. Oktober zeigt, wie man das passende Modell auswählt, die Infrastruktur aufbaut und die Sicherheit im Griff behält. Außerdem gibt der Thementag von iX und dpunkt.verlag einen Ausblick auf Liquid Foundation Models als nächste Generation von LLMs.
Weitere Updates in diesem VS-Code-Release umfassen eine verbesserte Barrierefreiheit, das Konfigurieren des Autostart-Verhaltens für MCP-Server und die Überarbeitung des Tool Picker. Alle Details zu den Neuerungen finden sich im Ankündigungsbeitrag von Microsoft.
(mai)
Entwicklung & Code
Künstliche Neuronale Netze im Überblick 3: Aktivierungsfunktionen
Neuronale Netze sind der Motor vieler Anwendungen in KI und GenAI. Diese Artikelserie gibt einen Einblick in die einzelnen Elemente.
Prof. Dr. Michael Stal arbeitet seit 1991 bei Siemens Technology. Seine Forschungsschwerpunkte umfassen Softwarearchitekturen für große komplexe Systeme (Verteilte Systeme, Cloud Computing, IIoT), Eingebettte Systeme und Künstliche Intelligenz.
Er berät Geschäftsbereiche in Softwarearchitekturfragen und ist für die Architekturausbildung der Senior-Software-Architekten bei Siemens verantwortlich.
Der dritte Teil zeigt, wie Operationen den Vorwärtsdurchlauf in seiner Allgemeinheit bilden und wie die Wahl der Aktivierungen mit der Netzwerktiefe zusammenwirkt.
Vorwärtsausbreitung, auch Vorwärtsdurchlauf genannt, bezeichnet den Prozess der Berechnung der Ausgabe eines neuronalen Netzwerks durch sukzessive Anwendung linearer Transformationen und nicht linearer Aktivierungsfunktionen auf die Eingabedaten. Für eine einzelne Schicht ℓ gilt, wenn wir die Aktivierungen der vorherigen Schicht mit a^(ℓ–1), die Matrix der Gewichte der Schicht mit W^(ℓ) und den Bias-Vektor mit b^(ℓ) bezeichnen, dann berechnet die Schicht den Präaktivierungsvektor z^(ℓ) als
z^(ℓ) = W^(ℓ) · a^(ℓ–1) + b^(ℓ)
Nach der Berechnung von z^(ℓ) wendet die Schicht eine elementweise nicht lineare Aktivierungsfunktion σ an, um die Ausgangsaktivierungen zu erzeugen:
a^(ℓ) = σ(z^(ℓ)).
Durch Zusammensetzen dieser Operationen für jede Schicht vom Eingang bis zum Ausgang wandelt das Netzwerk einen anfänglichen Eingabevektor in einen endgültigen Ausgabevektor um, der eine Vorhersage oder eine Merkmals-Einbettung darstellt.
Um diese Berechnungen konkret zu veranschaulichen, betrachten wir eine Gruppe von Eingabevektoren, die wir als Matrix X
mit der Form (batch_size, input_dim)
darstellen. Eine vollständig verbundene Schicht in PyTorch lässt sich manuell wie folgt implementieren, wobei W
die Form (output_dim, input_dim)
und b
die Form (output_dim)
hat:
import torch
batch_size = 32
input_dim = 10
output_dim = 50
# Simulieren Sie einen Stapel von Eingaben
X = torch.randn(batch_size, input_dim)
# Initialisieren Sie die Gewichtungsmatrix und den Bias-Vektor
W = torch.randn(output_dim, input_dim)
b = torch.randn(output_dim)
# Berechnen Sie die Voraktivierung für den Stapel: Z = X @ W^T + b
Z = X.matmul(W.t()) + b
# Wende eine Nichtlinearität (z. B. ReLU) an, um Aktivierungen A zu erhalten
A = torch.relu(Z)
In diesem Ausschnitt enthält der Tensor X
zu Demonstrationszwecken zufällige Werte. Der Ausdruck W.t()
bezeichnet die Transponierung von W
, die die Form (input_dim, output_dim)
hat. Die Batch-Matrixmultiplikation X.matmul(W.t())
erzeugt einen neuen Tensor Z
mit der Form (batch_size, output_dim)
, da jede der batch_size
-Zeilen von X mit Wᵀ multipliziert wird. Durch Hinzufügen von b
zu Z
übertragen wir den Bias-Vektor auf alle Zeilen, wodurch wir die vollständigen Voraktivierungswerte erhalten. Zuletzt führt torch.relu
eine elementweise rektifizierte lineare Einheit auf Z
aus, um A
zu erzeugen.
Aktivierungsfunktionen führen die Nichtlinearität ein, die es neuronalen Netzen ermöglicht, komplexe Muster zu lernen. Die logistische Sigmoid-Funktion, definiert durch
σ(z) = 1 / (1 + exp(−z)),
bildet jede reelle Eingabe in den Bereich zwischen null und eins ab. Ihre Ableitung kann in Bezug auf ihre Ausgabe ausgedrückt werden als
σ′(z) = σ(z) · (1 − σ(z)).
Obwohl Sigmoid in der Vergangenheit sehr beliebt war, können seine Gradienten sehr klein werden, wenn |z| groß ist, was zu einem langsamen Lernen in der Tiefe eines Netzwerks führt.
In PyTorch können Sie eine Sigmoid-Aktivierung für einen Tensor Z mit folgendem Befehl berechnen:
A_sigmoid = torch.sigmoid(Z)
wobei torch.sigmoid
die elementweise logistische Funktion auf jeden Eintrag von Z anwendet und einen neuen Tensor mit Werten zwischen null und eins erzeugt.
Die hyperbolische Tangensfunktion, definiert durch
tanh(z) = (exp(z) − exp(−z)) / (exp(z) + exp(−z)),
bildet reelle Eingaben auf den Bereich zwischen minus eins und eins ab. Ihre Ableitung ist gegeben durch 1 − tanh(z)^2. Da tanh nullzentriert ist, führt sie oft zu einer schnelleren Konvergenz als Sigmoid, leidet jedoch bei großen positiven oder negativen Eingaben unter verschwindenden Gradienten.
In PyTorch können Sie eine tanh-Aktivierung mit folgendem Befehl berechnen:
A_tanh = torch.tanh(Z)
Die in modernen tiefen Netzwerken am häufigsten verwendete Aktivierung ist die rektifizierte lineare Einheit (ReLU), definiert als
ReLU(z) = max(0, z)
Ihre Ableitung ist immer null, wenn z negativ ist, und immer eins, wenn z positiv ist. Diese einfache, stückweise lineare Form vermeidet eine Sättigung bei positiven Eingaben, was das Problem der verschwindenden Gradienten erheblich mildert. Allerdings können Neuronen während des Trainings „sterben“, wenn ihre Eingaben negativ werden und negativ bleiben, was zu dauerhaft null-Gradienten führt.
Sie können eine ReLU-Aktivierung in PyTorch entweder mit torch.relu
oder durch Erstellen einer Instanz des Moduls
anwenden:
A_relu = torch.relu(Z)
import torch.nn as nn
relu_layer = nn.ReLU()
A_relu_mod = relu_layer(Z)
Um das Problem des „sterbenden ReLU“ zu beheben, führt Leaky ReLU eine kleine Steigung α für negative Eingaben ein, definiert als
LeakyReLU(z) = max(α·z, z).
Ihre Ableitung ist α, wenn z negativ ist, und eins, wenn z positiv ist. Eine typische Wahl für α ist 0,01. Im Code können Sie eine leaky ReLU-Schicht in PyTorch mit folgendem Code erstellen und anwenden:
leaky_relu = nn.LeakyReLU(negative_slope=0.01)
A_leaky = leaky_relu(Z)
Bei der Klassifizierung über mehrere Klassen wird die Softmax-Funktion verwendet, um einen Vektor mit beliebigen reellen Werten in eine Wahrscheinlichkeitsverteilung umzuwandeln. Für einen Vektor z mit Komponenten z_i gilt
softmax(z)_i = exp(z_i) / Σ_j exp(z_j).
Die Jacobi-Matrix von Softmax hat Einträge ∂σ_i/∂z_j = σ_i (δ_{ij} − σ_j). In der Praxis wird Softmax typischerweise mit dem Kreuzentropieverlust kombiniert, was zu einem numerisch stabilen und einfacheren kombinierten Gradienten führt. In PyTorch lässt sich Softmax entlang einer bestimmten Dimension anwenden. Für einen Batch von Logits mit dem Namen logits und der Form (batch_size, num_classes)
können Sie beispielsweise schreiben:
import torch.nn.functional as F
probabilities = F.softmax(logits, dim=1)
Das berechnet die Exponentialfunktionen jeder Zeile in logits, normalisiert sie anhand der Zeilensummen und gibt einen Tensor derselben Form zurück, der Werte zwischen null und eins enthält, die entlang jeder Zeile eins ergeben.
Über diese klassischen Aktivierungen hinaus haben neuere Funktionen wie Swish, definiert als z · sigmoid(z), und GELU, die Gaußsche Fehlerlineareinheit, für bestimmte Architekturen an Beliebtheit gewonnen, da sie glattere Gradienten und eine verbesserte Leistung bei Aufgaben wie der Sprachmodellierung bieten. Obwohl diese Funktionen in Bibliotheken wie PyTorch (z. B. über das Modul nn.GELU
) verfügbar sind, bleiben ReLU und seine Varianten aufgrund ihres zusätzlichen Rechenaufwands für viele Praktiker die Standardwahl.
Nachdem wir nun sowohl die linearen Transformationen, aus denen die Voraktivierungen jeder Schicht bestehen, als auch die darauffolgenden nicht linearen Aktivierungsfunktionen behandelt haben, sind wir in der Lage, tiefe neuronale Netze zu bauen, die Eingabedaten in reichhaltige interne Darstellungen umwandeln.
Der nächste Teil der Serie zeigt, wie gut die Vorhersagen eines Netzwerks mit den gewünschten Zielen übereinstimmen, indem man Verlustfunktionen einführt. Anschließend zeigt der Beitrag gradientenbasierten Optimierungsalgorithmen, mit denen sich die Parameter des Netzwerks anpassen lassen.
(rme)
-
Datenschutz & Sicherheitvor 2 Monaten
Geschichten aus dem DSC-Beirat: Einreisebeschränkungen und Zugriffsschranken
-
Online Marketing & SEOvor 2 Monaten
TikTok trackt CO₂ von Ads – und Mitarbeitende intern mit Ratings
-
Apps & Mobile Entwicklungvor 2 Monaten
Metal Gear Solid Δ: Snake Eater: Ein Multiplayer-Modus für Fans von Versteckenspielen
-
Digital Business & Startupsvor 1 Monat
10.000 Euro Tickets? Kann man machen – aber nur mit diesem Trick
-
UX/UI & Webdesignvor 2 Monaten
Philip Bürli › PAGE online
-
Digital Business & Startupsvor 1 Monat
80 % günstiger dank KI – Startup vereinfacht Klinikstudien: Pitchdeck hier
-
Apps & Mobile Entwicklungvor 1 Monat
Patentstreit: Western Digital muss 1 US-Dollar Schadenersatz zahlen
-
Social Mediavor 2 Monaten
Aktuelle Trends, Studien und Statistiken