Connect with us

Entwicklung & Code

Apple übernimmt Entwickler des Open Policy Agents


Open Policy Agent (OPA) ist eine Software, die Regeln (formuliert in der Sprache Rego) und Datenobjekte entgegennimmt und auf dieser Grundlage Entscheidungen trifft – Haupteinsatzgebiet sind Autorisierungsregeln, die die Frage beantworten, ob ein Nutzer eine Aktion ausführen darf. Weil OPA Open-Source-Software ist (Apache License 2.0) und vergleichsweise leicht in andere Anwendungen integriert werden kann, erfreut er sich großer Beliebtheit in der Cloud-Native-Community: OPA wird unter anderem genutzt, um über Anfragen ans Kubernetes-API zu entscheiden, trifft in Banken aber auch Entscheidungen, wer welche Anfragen an interne Systeme stellen darf.

Erfunden wurde OPA vom Unternehmen Styra, das mit Zusatzprodukten und Dienstleistungen rund um OPA Geld verdient hat. Auf der Homepage findet man die Logos von Zalando, CapitalOne und dem Europäischen Patentamt. Auch Goldman Sachs und Netflix gehört zu den OPA-Nutzern. Der Code von OPA selbst liegt aber nicht mehr in der Hand von Styra: 2018 wurde OPA als Incubating-Projekt von der CNCF (Cloud Native Computing Foundation) akzeptiert, seit 2021 hat es den höchsten Status „Graduated“ erreicht und hat insgesamt 485 Contributors.

Jetzt steht der nächste Umbruch an: Die Erfinder von Open Policy Agent sowie weitere Mitarbeiter des Unternehmens Styra wechseln den Arbeitgeber: Apple, ebenfalls OPA-Nutzer, übernimmt Styra-CTO Tim Hinrichs und weitere Entwickler. Das hat Hinrichs im OPA-Blog verkündet. „Apple ist ein enthusiastischer OPA-Nutzer, der es als zentrale Komponente seiner Autorisationsinfrastruktur nutzt, um ein großes Portfolio globaler Clouddienste zu verwalten.“

Weil der Code bereits in der Hand der CNCF liegt, ändert sich das Open-Source-Projekt nichts. Der Code bleibt Open Source und wird wie zuvor von der CNCF verwaltet. Auch die Liste der Maintainer soll sich nicht ändern. Neu ist vielmehr, dass Zusatzprodukte aus dem Styra-Portfolio ebenfalls Open Source werden und ins öffentliche Repository umziehen: die kommerzielle OPA-Distribution EOPA, die Verwaltungsoberfläche „OPA Control Plane“, mehrere SDKs sowie der Rego-Linter namens Regal.

Website und Rego-Playground (eine Website, um Rego-Regeln zu testen) sollen wie gewohnt weiterlaufen und auch die Entwicklung soll weitergehen. Unklar hingegen ist, in welcher Form das Unternehmen Styra weiterarbeiten wird. Dazu macht der Blogpost keine Angaben. Große Organisationen, die gehofft haben, bei Styra die Autorisierungsexpertise und Beratung von Tim Hinrichs und den anderen OPA-Kernentwicklern einkaufen zu können, gehen leer aus: Diese Expertise nutzt jetzt Apple.


(jam)



Source link

Entwicklung & Code

software-architektur.tv: Netflix ohne Bounded Contexts


In der Softwarearchitektur gilt: Systeme lassen sich besser warten und flexibler gestalten, wenn man sie in mehrere Bounded Contexts aufteilt – und das ist gerade bei Microservices-Systemen entscheidend. Doch nun hat ausgerechnet Netflix, ein Pionier der Microservices-Bewegung, einen Blogpost veröffentlicht, der einen ganz anderen Weg propagiert: „Model Once, Represent Everywhere: UDA (Unified Data Architecture)„.

In dieser Episode nimmt Eberhard Wolff den Ansatz von Netflix genauer unter die Lupe und diskutiert, ob die Zeit gekommen ist, die Idee klar getrennter Bounded Contexts infrage zu stellen – und stattdessen auf ein zentrales Modell zu setzen.

Lisa Maria Schäfer malt dieses Mal keine Sketchnotes.

Die Ausstrahlung findet live am Freitag, 22. August 2025, 13 bis 14 Uhr statt. Die Folge steht im Anschluss als Aufzeichnung bereit. Während des Livestreams können Interessierte Fragen via Twitch-Chat, YouTube-Chat, Bluesky, Mastodon, Slack-Workspace oder anonym über das Formular auf der Videocast-Seite einbringen.

software-architektur.tv ist ein Videocast von Eberhard Wolff, Blogger sowie Podcaster auf iX und bekannter Softwarearchitekt, der als Head of Architecture bei SWAGLab arbeitet. Seit Juni 2020 sind über 250 Folgen entstanden, die unterschiedliche Bereiche der Softwarearchitektur beleuchten – mal mit Gästen, mal Wolff solo. Seit mittlerweile mehr als zwei Jahren bindet iX (heise Developer) die über YouTube gestreamten Episoden im Online-Channel ein, sodass Zuschauer dem Videocast aus den Heise Medien heraus folgen können.

Weitere Informationen zur Folge finden sich auf der Videocast-Seite.


(mdo)



Source link

Weiterlesen

Entwicklung & Code

Immer mehr performance-kritischer Rust-Code in der Python-Welt


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Rust wird immer wichtiger im Python-Ökosystem. Der aktuelle Report State of Python 2025 von der Python Software Foundation (PSF) und JetBrains zeigt, dass Rust zunehmend C als nativen Code für Module und Erweiterungen ersetzt, wenn Performance gefragt ist.

Bei binären Erweiterungen stieg laut des Reports der Anteil von Rust als Sprache von 27 auf 33 Prozent, was ein Plus von 22 Prozent bedeutet. In einem Blogbeitrag zur Studie ergänzt PSF-Mitglied Michael Kennedy, dass ein Viertel bis ein Drittel des nativen Codes für neue Projekte, der bei PyPI hochgeladen wird, Rust verwendet. Dabei zitiert er David Hewitt vom Python Language Summit 2025: „Leute, die neue Projekte starten, nehmen Rust“.


Infografik zu Rust

Infografik zu Rust

Der Anteil an Rust für binäre Module steigt.

(Bild: JetBrains)

Kennedy fasst zusammen: „Rust wird Pythons Performance-Copilot“ und liefert in seinem Beitrag eine Reihe von Beispielen:

  • Polars verwaltet Dataframes und basiert auf dem Format von Apache Arrows. Es gilt in vielen Punkten um das Fünf- bis Zehnfache schneller als Pandas bei weniger Speicherverbrauch.
  • Pydantic dient der Datenvalidierung und ist in allen Python-Bereichen eine sinnvolle Erweiterung.
  • Granian ist ein HTTP-Server für Python-Anwendungen
  • ty, der sehr schnelle Python Typen-Checker, verfügt über einen eigenen Language Server (LSP).
  • Pyrefly von Meta bietet ähnliche Funktionen wie ty, ebenso mit Language Server.
  • uv hat als Paket- und Projektmanager für Python in der aktuellen Studie – im Jahr seiner Veröffentlichung – einen Aufschwung von 0 auf 11 Prozent bei den Tools zur Code-Isolierung (Packen und Virtualisieren) gemacht. Dieser Trend setzt sich laut Kennedy dieses Jahr fort. Die Studie nächstes Jahr wird es zeigen.


Infografik uv

Infografik uv

uv startet im aktuellen Report von 0 auf 11 Prozent.

(Bild: JetBrains)

Am Schluss seines Beitrags empfiehlt Kennedy Python-Usern unter anderem, den Paketmanager uv auszuprobieren und sich ein Basiswissen an Rust anzueignen – nicht um Python zu ersetzen, sondern um es zu ergänzen: „Rust wird in den wichtigsten Teilen des Python-Ökosystems zunehmend bedeutender.“


Rostige Werkzeuge

Rostige Werkzeuge

(Bild: evgeeenius/Shutterstock)

Am 10. November findet die betterCode() Rust 2025 statt. Die fünfte Auflage der von iX und dpunkt.verlag ausgerichteten Online-Konferenz hat das Thema industrielle Anwendungen mit Rust im Fokus.

Das Programm der Konferenz bietet folgende Vorträge:

  • Rust in the automotive industry at Volvo
  • Performante Programmierung mit Rust
  • Asynchrones Rust: Alle Konzepte für den Start
  • Mit Rust auf Heldenreise
  • KI für die Rust-Entwicklung
  • Zusammenspiel von Rust mit C++


(who)



Source link

Weiterlesen

Entwicklung & Code

Künstliche Neuronale Netze im Überblick 5: Trainingsschleifen und Batching


Neuronale Netze sind der Motor vieler Anwendungen in KI und GenAI. Diese Artikelserie gibt einen Einblick in die einzelnen Elemente. Der erste Teil stellt das künstliche Neuron vor. Der fünfte Teil der Serie erstellt eine vollständige Trainingsschleife, zeigt die Unterschiede zwischen dem Training mit und ohne explizite Mini-Batches und stellt schließlich Techniken wie Dropout und Gewichtsabnahme zur Verbesserung der Generalisierung vor.


Michael Stal

Michael Stal

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.

Um einem Netzwerk beizubringen, seinen Verlust zu minimieren, muss man wiederholt Daten präsentieren, Vorhersagen berechnen, Fehler messen, Gradienten propagieren und Parameter aktualisieren. Dieser Berechnungszyklus bildet die Trainingsschleife. Je nach Rechenressourcen und Problemdimensionen kann man sich dafür entscheiden, den gesamten Datensatz auf einmal, eine Probe nach der anderen oder mehrere Proben, die zu Mini-Batches gruppiert sind, zu verarbeiten.

Eine grundlegende Trainingsschleife in PyTorch beginnt mit der Definition eines Datenladers, der Batches von gelabelten (Eingabe-Ziel-) Paaren liefert, der Instanziierung eines Optimierers und einer Verlustfunktion und der anschließenden Iteration über Epochen. Nachfolgend finden Sie ein vollständiges Beispiel, das Mini-Batches verwendet. Jeder Teil des Codes wird ausführlich erklärt.


import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# Angenommen, wir haben einen Merkmals-Tensor X der Form (1000, 20) und einen Ziel-Tensor y der Form (1000,)
dataset = TensorDataset(X, y)
# Erstellen Sie einen DataLoader, der Batches der Größe 32 ausgibt und jede Epoche mischt
data_loader = DataLoader(dataset, batch_size=32, shuffle=True)

model = SimpleMLP(input_dim=20, hidden_dim=50, output_dim=1)
loss_fn = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

num_epochs = 20
for epoch in range(num_epochs):
    epoch_loss = 0.0
    # Iterieren Sie über den Datensatz in Mini-Batches
    for batch_inputs, batch_targets in data_loader:
        # Setzen Sie die aus dem vorherigen Schritt akkumulierten Gradienten auf Null
        optimizer.zero_grad()
        # Berechnen Sie die Modellvorhersagen für den aktuellen Batch
        batch_predictions = model(batch_inputs)
        # Berechne den Verlust zwischen Vorhersagen und tatsächlichen Zielen
        loss = loss_fn(batch_predictions, batch_targets)
        # Backpropagation durch das Netzwerk, um Gradienten zu berechnen
        loss.backward()
        # Aktualisiere die Modellparameter basierend auf den Gradienten
        optimizer.step()

        # Akkumuliere den Verlustwert für die Berichterstellung
        epoch_loss += loss.item() * batch_inputs.size(0)
    # Teile durch die Gesamtzahl der Samples, um den durchschnittlichen Verlust zu erhalten
    epoch_loss /= len(dataset)
    print(f"Epoch {epoch+1}/{num_epochs}, Verlust: {epoch_loss:.4f}")


Der Code fasst zunächst die Merkmals- und Ziel-Tensoren in einem TensorDataset zusammen, das jede Eingabe mit der entsprechenden Beschriftung verknüpft. Anschließend erstellt er einen DataLoader, der in jeder Epoche Teilmengen der Daten in zufälliger Reihenfolge mit einer Größe von 32 ausgibt. Die Instanziierung des Modells, der Verlustfunktion und des Optimierers folgt den zuvor beschriebenen Mustern.

Die äußere Schleife verarbeitet die Daten für num_epochs vollständige Durchläufe. Innerhalb dieser Schleife initialisieren wir eine laufende Summe für den Verlust der Epoche. Jedes Mal, wenn der DataLoader einen Stapel von Eingaben und Zielen ausgibt, löscht die Anwendung alle vorherigen Gradienteninformationen, indem sie optimizer.zero_grad() aufruft. Die Berechnung von model(batch_inputs) ruft die Vorwärtsmethode des Netzwerks auf und liefert Vorhersagen. Der Code vergleicht diese Vorhersagen mit den tatsächlichen Zielen, indem er die Verlustfunktion aufruft, die einen skalaren Tensor erzeugt.

Der Aufruf von loss.backward() löst die automatische Differenziation von PyTorch aus, um die Gradienten des Verlusts in Bezug auf jeden lernbaren Parameter im Modell zu berechnen. Diese Gradienten werden im Attribut .grad jedes Parameters gespeichert. Der Aufruf von optimizer.step() ändert dann die Parameterwerte an Ort und Stelle gemäß der ausgewählten Aktualisierungsregel (in diesem Fall stochastischer Gradientenabstieg mit Momentum). Wir multiplizieren loss.item() mit der Batchgröße, um die Summe der Verluste pro Stichprobe zu ermitteln, akkumulieren diese und dividieren sie am Ende durch die Datensatzgröße, um den durchschnittlichen Verlust für die Epoche anzugeben.

Das Training ohne explizite Mini-Batches ist möglich, indem wir den gesamten Datensatz als einen Batch (Stapel) behandeln. In diesem Fall kann man den DataLoader überspringen und schreiben:


# Alle Daten als einen einzigen Batch behandeln
optimizer.zero_grad()
predictions = model(X)
loss = loss_fn(predictions, y)
loss.backward()
optimizer.step()


Dieser Full-Batch-Ansatz liefert zwar bei jedem Schritt den tatsächlichen Gradienten, kann jedoch bei großen Datensätzen ineffizient sein und mehr Speicherplatz als verfügbar erfordern. Umgekehrt kann die Verwendung von Einzelproben-Updates (stochastisch) durch Setzen von batch_size=1 im DataLoader zu einer hohen Varianz in der Gradientenschätzung führen, was zu einer verrauschten Konvergenz führt, die jedoch leichter aus flachen lokalen Minima entkommen kann. Mini-Batches stellen einen pragmatischen Kompromiss dar, indem sie die Varianz reduzieren und gleichzeitig die Speicherbeschränkungen einhalten.

Selbst wenn wir dieses Trainingsverfahren befolgen, können große neuronale Netze die Trainingsdaten überanpassen und statt Muster zu lernen, die sich auf neue Beispiele verallgemeinern lassen, zum Rauschen führen. Um die Überanpassung zu verringern, kann man Techniken für die Regularisierung anwenden.

Gewichtsabnahme, mathematisch äquivalent zur L2-Regularisierung, fügt dem Verlust eine Strafe proportional zur quadrierten Norm der Gewichte hinzu. In der Praxis signalisiert man dem Optimierer die Gewichtsabnahme. Um beispielsweise einen Koeffizienten von 1e-4 zu jedem Parameter außer den Biases hinzuzufügen, schreibt man:


optimizer = optim.SGD(
    [
        {'params': model.fc1.weight, 'weight_decay': 1e-4},
        {'params': model.fc2.weight, 'weight_decay': 1e-4},
        {'params': model.fc1.bias, 'weight_decay': 0},
        {'params': model.fc2.bias, 'weight_decay': 0}
    ],
    lr=0.01,
    momentum=0.9
)


Durch die Angabe von weight_decay für jede Parametergruppe fügt der Optimierer weight_decay * θ zum Gradienten jedes Gewichts hinzu und führt so effektiv die Aktualisierungsregel

θ ← θ − η ( ∂L/∂θ + λ · θ )

für jedes Gewicht θ aus, wobei λ der Gewichtsabklingkoeffizient ist.

Eine weitere leistungsstarke Regularisierungstechnik ist Dropout. Während des Trainings setzt Dropout bei jedem Vorwärtsdurchlauf zufällig einen Bruchteil p der Aktivierungen jeder Schicht auf Null, wodurch eine gegenseitige Anpassung der Neuronen verhindert wird. Zum Testzeitpunkt erfolgt die Deaktivierung von Dropout und die Skalierung der Aktivierungen um (1–p), um sie an die erwartete Größe anzupassen. In PyTorch fügt man Dropout-Schichten in die Modelldefinition ein. Um beispielsweise Dropout nach der ersten versteckten Schicht hinzuzufügen:


import torch.nn as nn

class MLPWithDropout(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, p=0.5):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.dropout = nn.Dropout(p=p)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        # Randomly zero a fraction p of elements during training
        x = self.dropout(x)
        x = self.fc2(x)
        return x


Wenn sich das Modell im Trainingsmodus befindet – was sich durch den Aufruf von model.train() sicherstellen lässt –, erfolgt bei jedem Vorwärtsdurchlauf die Auswahl einer neuen zufälligen Binärmaske, die einen Bruchteil p der Elemente in der versteckten Darstellung auf Null setzt. Durch den Aufruf von model.eval() vor dem Auswerten der Validierungsdaten lässt sich Dropout deaktivieren und der gesamte Satz von Aktivierungen verwenden.

Über den Gewichtsabbau und Dropout hinaus kann Early Stopping vor Overfitting schützen, indem die Leistung anhand eines Holdout-Validierungssatzes überwacht und das Training abgebrochen wird, wenn sich der Validierungsverlust nicht mehr verbessert. In der Regel speichert man die Modellparameter, wenn der Validierungsverlust abnimmt, und beendet das Training, wenn über eine bestimmte Anzahl von Epochen keine Verbesserung mehr auftritt.

Mit diesen Regularisierungsstrategien kann man tiefere und breitere Netzwerke trainieren und gleichzeitig eine robuste Generalisierung aufrechterhalten. Im nächsten Kapitel werden wir auf dieser Grundlage aufbauen und konvolutionale neuronale Netzwerke, rekurrenten Netzwerke und hybride Architekturen untersuchen, die mehrere Schichttypen kombinieren.


(rme)



Source link

Weiterlesen

Beliebt