1
 
 
Profil
In deinem persönlichen Profilbereich kannst du den Status deiner Bewerbung einsehen, unvollständige Bewerbungen zwischenspeichern und aktuelle News und Events einsehen
08. März 2023

Programmatische Werbung in Echtzeit mit TensorFlow

Worum geht es in dem Artikel?

Im Jahr 2018 entwickelte die OTTO BI (Team Siggi) in Zusammenarbeit mit dem Online Marketing eine hauseigene Programmatic Advertising Lösung. Hierfür wurde unter anderem eine eigene SSP (Supply Side Platform) und DSP (Demand Side Platform) Lösung entwickelt – genannt Orbidder.

Die Hintergründe rund um die SSP, die DSP und wie diese Services zusammenarbeiten, wurden bereits von unserem Kollegen Dr. Rainer Volk in diesem Blog Post beschrieben.

Seit 2019 ist der Orbidder live und nimmt täglich 1 – 1,2 Milliarden Bid Requests entgegen und steuert, über im Hintergrund laufende Data Science Modelle, mehr als 300 aktive Marketingkampagnen zeitgleich. Anfang 2022 wurde entschieden, dass über die initial mit dem Vertrieb aufgesetzte Lösung, zur Steuerung von vermarkteten Werbekampagnen auf externen Webseiten, nun auch für die Steuerung von otto.de Flächen zum Einsatz kommen soll. Dies führte zu neuen Anforderungen an die Systemlandschaft und die Steuerungslogik. Im nachfolgenden Post möchten wir darauf eingehen, wie wir diese neuen Anforderungen umgesetzt haben.


Problemstellung

Grundsätzlich funktioniert die SSP/DSP Lösung wie in Abbildung 1 schematisch dargestellt. Bid Requests für Ad Slots (auch Placement genannt) werden über openRTB bzw. einen prebid.js Adapter an die SSP übermittelt. Von dort werden sie aufbereitet an die DSP weitergeleitet. In der DSP erfolgt die Gebotsermittlung, auf Basis der von einem Data Science Team bereitgestellten Modelle. Das errechnete Gebot wird zurückgegeben und für eine Auktion verwendet. Sollte diese gewonnen werden, wird anschließend ein Werbemittel angezeigt.

Basic structure of the SSP/DSP
Basic structure of the SSP/DSP

Abbildung 1: Grundsätzlicher Aufbau SSP/DSP

Mit der Anbindung von otto.de ergaben sich eine Reihe von Anforderungen, die mit dem bis dato laufenden Setup nicht abbildbar waren.

Bisher wurden für alle bekannten Nutzer (bekannt im Sinne von: besitzt einen Otto Cookie), in einem alle 2 Stunden laufenden Batch Prozess vorab ermittelt, welche Kampagne auf Basis von diversen Features (Klickhistorie, abgebrochene Warenkörbe, etc.) gut passen könnte. Dieses Userspezifische Assignment wurde dann exportiert und in der DSP hinterlegt. Durch diese Vorberechnung und durch die Fokussierung auf eine Kampagne je User, ergaben sich zwei technische Probleme. Zusätzlich dazu gab es eine organisatorische Herausforderung.

User assignment
User assignment

Abbildung 2: User Assignment

Problem 1 – Keine Kampagne zur aktuellen Seite

Was passiert nun, wenn ein Nutzer auf otto.de zum Beispiel auf eine Angebotsseite mit Tablets oder Smartphones kommt?

Problem 1
Problem 1

Abbildung 3: Problem 1

Im Beispiel 1 landet User 1 auf der Seite für Multimedia. Obwohl ihm die Kampagne „Technik“ zugewiesen wurde, passt der Scope in diesem Fall nicht. Hintergrund ist, dass für diesen Kunden die optimale Klickwahrscheinlichkeit auf externen Seiten liegt. Somit würde diesem Kunden kein Banner auf otto.de angezeigt werden. Im Beispiel 2 ruft User 3 die Seite auf. Für ihn wurde zwar ein Onsite Scope berechnet, aber er befindet sich im falschen Kontext, eben Technik und nicht wie berechnet Fashion. Also: wieder keine Ausspielung.

Problem 2 – Kampagnen und Werbemittel je Seite und nicht je Placement

Was passiert eigentlich auf Webseiten, auf denen es mehrere Ad Slots oder Placements gibt? Für unser Beispiel passen wir die User Assignment Tabelle einmal an. User 1 ist nun einer zum Scope passenden Kampagne zugeordnet.

Problem 2
Problem 2

Abbildung 4: Problem 2

Ein Bid Request umfasst üblicherweise immer alle Placements / Ad Slots auf einer Webseite. Gebote werden nun zwar für alle Placements einzeln abgegeben, allerdings erfolgt das bisherige Assignment auf Basis von Batch Prozessen. Dadurch ist ein User immer für 2 Stunden nur genau einer Kampagne zugeordnet. Wenn nun auf einer Webseite 3 Placements zur Verfügung stehen und es werden 2 Placements gewonnen, dann wird auf beiden Placements die gleiche Kampagne und damit auch das gleiche Werbemittel ausgespielt.
In unserem Beispiel wurde für User 1 eine Technik Kampagne berechnet, die auch den richtigen Scope hat. Es fallen also alle Werbeplätze auf der Seite der gleichen Kampagne zu, was dann in der Ausspielung ähnlicher Werbemittel auf allen Placements resultiert.

Aufteilung von Verantwortlichkeiten auf mehrere Teams

Zusätzlich zu den zwei oben genannten Problemen kam noch eine weitere Herausforderung hinzu. Es handelt sich dabei weniger um ein technisches oder fachliches als vielmehr ein organisatorisches Thema. Frei nach Wikipedia besagt das Gesetz von Conway folgendes:

„Organisationen, die Systeme entwerfen, […] sind gezwungen, Entwürfe zu erstellen, die die Kommunikationsstrukturen dieser Organisationen abbilden.“

Dieses Gesetz spiegelt sich auch in unserem Produkt wider. Der Betrieb der SSP/DSP Infrastruktur sowie die Ausführung der Modellergebnisse lagen bei einem Team, die Data Science Modelle bei einem anderen Team. Was dies für Schwierigkeiten mit sich bringen kann, kann man sich vielleicht denken. Allein durch die unterschiedlichen Programmiersprachen (Data Science Modelle in Python, DSP/SSP in GO) waren Änderungen und Test der Algorithmen nur schwer umzusetzen.
Im Ziel einer Weiterentwicklung stand also auch die Frage des Produktschnittes und ob es möglich wäre, dass beide Teams unabhängiger voneinander entwickeln können.


Lösung und Technologie Stack

Wie löst man nun diese Probleme? – Zunächst einmal mit Diskussionen.
In gemeinsamen Runden zwischen den Entwicklern beider Teams wurden die Kernanforderungen zusammengefasst:

  • Berechnung des User Assignments je Ad Slot/ Placement, d.h. nicht mehr nur eine Kampagne je User
  • Berücksichtigung des aktuellen Umfelds (Onsite, Offsite, App, Url) des Users
  • Unabhängigkeit in der Data Science Entwicklung

Um diese Anforderungen umzusetzen war es notwendig, die User deutlich schneller und flexibler einer Kampagne bzw. einem Placement zuzuweisen. Damit dabei noch Umfeldinformationen Berücksichtigung finden könnten, müsste die Berechnung in Realtime erfolgen. Somit stand fest: wir benötigen in Zukunft ein Realtime Assignment.

Ein Problem gelöst, standen wir nun vor der Umsetzung. Schnell wurde klar, dass die neuen Anforderungen mit der aktuellen Implementierung nicht umsetzbar waren. Was waren einige Probleme?

  • Die Bidfunktion darf nicht zu kompliziert werden, damit der CPM noch im low latency Bereich berechnet werden kann
  • Viele Daten müssen kurzfristig im Zugriff sein, dadurch würden sich die Zugriffe auf unsere Datenbank um circa das 1000x erhöhen
  • Datenmenge und Datengröße (z.B.: Features) würden sehr wachsen
  • Die Data Science Teams wären bei Änderungen stark limitiert

TensorFlow to the rescue

Wie schafft man es nun in Echtzeit die optimale Gebotshöhe und Kampagne zu berechnen? Diverse Faktoren wie Budget, relevante Kampagnen und verschiedenste User Features müssen in Millisekunden zur Verfügung stehen und schließlich über eine von den Data Scientisten zur Verfügung gestellte Formel in Relation zueinander gebracht werden. Und das alles mit einer sehr niedrigen Latenz.
Da eins unserer Ziele auch die Unabhängigkeit der Data Scientisten war, wollten wir die Implementierung einer aufwändigen und statischen Funktion direkt in einem Service vermeiden. Das Lesen und Schreiben großer Datenmengen in eine Datenbank scheiterte an der Geschwindigkeit und einzelne Schritte vorberechnen, war wiederum nicht flexibel genug, um den Problemstellungen gerecht zu werden.


TensorFlow Logo
TensorFlow Logo

Abbildung 5: TensorFlow Logo

Nach einiger Überlegung und Diskussion zeigte sich, dass die beste Möglichkeit die Nutzung eines Maschine Learning Frameworks wäre, was den Export eines kompletten, trainierten Models inkl. den zugehörigen Daten ermöglicht. Dieses exportierte Model müsste dann in einen Service integriert und über eine Schnittstelle aufgerufen werden.

 
So entstand der Ansatz TensorFlow und TensorFlow Serving zu verwenden, welches von Google entwickelt wurde, um genau diese Art des Use Cases zu vereinfachen. TensorFlow ist ein Framework, mit dem sich Aufgaben des maschinellen Lernens und der künstlichen Intelligenz umsetzen lassen. Durch TensorFlow können die Data Scientisten Modelle und Daten in einem exportierbaren Format kapseln, so die Kontrolle über die Algorithmen behalten und diese unabhängig verändern ohne das in der SSP oder DSP weiterer Entwicklungsaufwand notwendig ist. TensorFlow Serving bietet dabei eine einfache und hoch performante Möglichkeit die Modelle, nach dem Training, operativ zu betreiben. Im Wesentlichen können so die angereicherten Bid Requests per API an TensorFlow Serving geschickt und die Response, bestehend aus dem Gebot und der Kampagne, ausgelesen werden.

Request / Response

Für die Berechnung wurde ein Großteil der Daten bzw. Features schon in die TensorFlow Modelle hinein implementiert und dann als ‚saved model‘ exportiert, wodurch die Modelle mit + 15 GB sehr groß sind. Die Modelle werden durch den Model Server von TensorFlow Serving komplett in den ORBIDDER geladen. Dies ermöglicht eine sehr schnelle Ausführung des Modelcodes und Antwortzeiten im 10 – 20 Millisekunden Bereich.

Für die Berechnung der Gebote und der Kampagnen fehlen dann nur noch die angereicherten Bid Requests. Darin enthalten sind neben der UserId, auch Informationen zu Kampagnen, Kontext und Budget. Der Model Server von TensorFlow Serving stellt out-of-the-box Schnittstellen für gRPC und REST zur Verfügung, über die dann das Model angesprochen werden kann.
Die Response wird dann in der SSP weiterverarbeitet und es wird ein Gebot für ein Placement abgegeben, was dann eventuell zu einer Impression und im allerbesten Fall auch zu einem Klick führt.

Zu den genaueren Inhalten der Gebotsberechnung gibt es von den Data Science Kolleg*innen hier einen Blog Artikel.

Architecture flow map

In dem anschließenden, vereinfachten Architekturbild ist die SSP/DSP Landschaft einmal aufgezeichnet. Anhand dieser lässt sich auch der Weg des Bid Requests durch die SSP/DSP ablesen. Weiterhin zeigt es einige kritische Komponenten, die im Anschluss kurz erläutert sind.

Architecture flow map
Architecture flow map

Abbildung 6: Architecture flow map

Kubernetes
Der Kubernetes Cluster besteht aus einzelnen Node Pools in unterschiedlichen Zonen, um den unterschiedlichen Anforderungen der Services gerecht zu werden (CPU vs. RAM).

Redis
Unser Applikationscache hält die Daten zwischen 1 und 60 Sekunden vor, danach aktualisiert er sich durch die Daten aus der Redis.

Cloud Storage
Für einfachen Dateiaustausch und zur Ablage und Archivierung von Daten, kommt Cloud Storage zum Einsatz.

PubSub
Ein Message Broker für die Übertragung der Bids, Impression und Klickevents, sowie von Kampagnenänderungen.

BigQuery
Data Warehouse zur dauerhaften Speicherung von Daten zur Verbesserung der Modelle und Algorithmen, sowie zur Abrechnung von Erlösen und Kosten.

Filestore
Da in GKE ein Storage nicht gleichzeitig lesend und schreibend in einen Pod gemounted werden kann, nutzen wir Filestore (NFS) um dies zu ermöglichen. Notwendig wird dies um TensorFlow Modelle ohne Downtime zu tauschen.

Prometheus / Grafana 
Aus unseren Services werden in Echtzeit Metriken generiert, die in Prometheus gespeichert und mit Grafana visualisiert werden.

TensorFlow Serving
Um die Modelle der Data Scientisten operativ laufen zu lassen, werden diese mit allen notwendigen Daten exportiert und anschließend mit TensorFlow Serving via REST mit Bid Requests angefragt.

Kennzahlen und Fakten über Orbidder

• 71 Milliarden Requests wurden von der Orbidder SSP im Oktober 2022 gehandelt
• Im Schnitt verarbeitet der Orbidder zwischen 25.000 und 30.000 Requests pro Sekunde
• 100.000 Request pro Sekunde ist der maximale registrierte Durchsatz der Requests an die Orbidder SSP
• 15 Millisekunden ist die durchschnittliche Latenz bei der Verarbeitung eines Requests
• Etwa 1000 ist die Anzahl der Service Instanzen (Pods) im GCP Kubernetes-Cluster vom Orbidder tagsüber

Orbidder & Nachhaltigkeit

Otto hat das Ziel bis 2030 klimaneutral zu sein. Die Klimaziel der Otto Group lassen sich am besten hier nachlesen.

In der Otto BI und damit auch beim Orbidder, versuchen wir diese Ziele immer im Blick zu halten. Leider ist es schwierig, den CO2 Ausstoß auf der Frontend Seite z.B. im Internetbrowser bei dem Ausspielen der Online-Werbung zu beeinflussen bzw. überhaupt messbar zu machen, aber auf der SSP/DSP Seite im Backend kann man sich bewusst für nachhaltigen Technologien entscheiden.

Die Google Cloud Platform bietet dabei eine breite Palette von Möglichkeiten, Services nachhaltig zu gestalten, so gibt es z. B. bei der Auswahl der Services immer die Möglichkeit zu sehen, wieviel CO2 durch eine Technologie oder einen Service verursacht wird.
Durchschnittlich produzieren die Komponenten vom Orbidder System etwa 1,6t. CO2 pro Monat. Ist das viel oder wenig? Studien zufolge entspricht dies dem CO2 Ausstoß von 6 Personen je Tag.

Lässt man die Grundsatzdiskussion über die Notwendigkeit von Werbung im Internet einmal komplett außer Acht, sind dies schon vergleichbar gute Werte. Die Rechenzentren in Belgien, wo unsere Services laufen, haben ein paar der niedrigsten Werte in Europa. Trotzdem Orbidder wir stetig daran Rechenoperationen zu verschlanken und somit den Ressourceneinsatz zu verringern.

Willst du Teil des Teams werden?

4 Personen gefällt das

0Noch keine Kommentare

Dein Kommentar
Antwort auf:  Direkt auf das Thema antworten

Geschrieben von

Michael Wilgosch
Michael Wilgosch
Entwickler, Team Siggi
Sergey Kovalchuk
Sergey Kovalchuk
Entwickler, Team Siggi

Ähnliche Beiträge

We want to improve out content with your feedback.

How interesting is this blogpost?

We have received your feedback.

Cookies erlauben?

OTTO und drei Partner brauchen deine Einwilligung (Klick auf "OK") bei einzelnen Datennutzungen, um Informationen auf einem Gerät zu speichern und/oder abzurufen (IP-Adresse, Nutzer-ID, Browser-Informationen).
Die Datennutzung erfolgt für personalisierte Anzeigen und Inhalte, Anzeigen- und Inhaltsmessungen sowie um Erkenntnisse über Zielgruppen und Produktentwicklungen zu gewinnen. Mehr Infos zur Einwilligung gibt’s jederzeit hier. Mit Klick auf den Link "Cookies ablehnen" kannst du deine Einwilligung jederzeit ablehnen.

Datennutzungen

OTTO arbeitet mit Partnern zusammen, die von deinem Endgerät abgerufene Daten (Trackingdaten) auch zu eigenen Zwecken (z.B. Profilbildungen) / zu Zwecken Dritter verarbeiten. Vor diesem Hintergrund erfordert nicht nur die Erhebung der Trackingdaten, sondern auch deren Weiterverarbeitung durch diese Anbieter einer Einwilligung. Die Trackingdaten werden erst dann erhoben, wenn du auf den in dem Banner auf otto.de wiedergebenden Button „OK” klickst. Bei den Partnern handelt es sich um die folgenden Unternehmen:
Google Ireland Limited, Meta Platforms Ireland Limited, LinkedIn Ireland Unlimited Company
Weitere Informationen zu den Datenverarbeitungen durch diese Partner findest du in der Datenschutzerklärung auf otto.de/jobs. Die Informationen sind außerdem über einen Link in dem Banner abrufbar.
Du kannst deine Einwilligung auch jederzeit grundlos mit Wirkung für die Zukunft widerrufen, indem du auf den Button "Cookie-Einstellungen" im Footer der Website und "Cookies ablehnen" klickst.