In dieser Anleitung erfahren Sie, wie Sie ein skalierbares ML-Modell (Machine Learning) mit dem TorchServe-Framework in einem Google Kubernetes Engine-Cluster (GKE) bereitstellen und ausführen. Sie stellen ein vortrainiertes PyTorch-Modell bereit, das Vorhersagen auf der Grundlage von Nutzeranfragen generiert. Nach der Bereitstellung des Modells erhalten Sie eine Vorhersage-URL, über die Ihre Anwendung Vorhersageanfragen sendet. Mit dieser Methode können Sie das Modell und die Webanwendung unabhängig voneinander skalieren. Wenn Sie die ML-Arbeitslast und ‑Anwendung in Autopilot bereitstellen, wählt GKE den effizientesten zugrunde liegenden Maschinentyp und die effizienteste Größe für die Ausführung der Arbeitslasten aus.
Diese Anleitung richtet sich an Entwickler für maschinelles Lernen (ML), Plattformadministratoren und ‑betreiber sowie an Daten- und KI-Spezialisten, die GKE Autopilot verwenden möchten, um den Verwaltungsaufwand für die Knotenkonfiguration, ‑skalierung und ‑upgrades zu reduzieren. Weitere Informationen zu gängigen Rollen und Beispielaufgaben, auf die wir in Google Cloud -Inhalten verweisen, finden Sie unter Häufig verwendete GKE Enterprise-Nutzerrollen und -Aufgaben.
Machen Sie sich vor dem Lesen dieser Seite mit dem GKE Autopilot-Modus vertraut.
Über die Anwendung in diesem Tutorial
Die Anwendung ist eine kleine Python-Webanwendung, die mit dem Fast Dash-Framework erstellt wurde. Über die Anwendung senden Sie Vorhersageanfragen an das T5-Modell. Diese Anwendung erfasst die Texteingaben der Nutzer und die Sprachpaare und sendet die Informationen an das Modell. Das Modell übersetzt den Text und gibt das Ergebnis an die Anwendung zurück, die es dem Nutzer anzeigt. Weitere Informationen zu Fast Dash finden Sie in der Fast Dash-Dokumentation.
Lernziele
- Vortrainiertes T5-Modell aus dem Repository Hugging Face für die Bereitstellung vorbereiten, indem es als Container-Image verpackt und in die Artifact Registry gepusht wird
- Modell in einem Autopilot-Cluster bereitstellen
- Fast Dash-Anwendung bereitstellen, die mit dem Modell kommuniziert
- Modell anhand von Prometheus-Messwerten automatisch skalieren
Kosten
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Hinweise
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine, Cloud Storage, Artifact Registry, and Cloud Build APIs:
gcloud services enable container.googleapis.com
storage.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com -
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine, Cloud Storage, Artifact Registry, and Cloud Build APIs:
gcloud services enable container.googleapis.com
storage.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com
Umgebung vorbereiten
Klonen Sie das Beispiel-Repository und öffnen Sie das Anleitungsverzeichnis:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
cd kubernetes-engine-samples/ai-ml/t5-model-serving
Cluster erstellen
Führen Sie dazu diesen Befehl aus:
gcloud container clusters create-auto ml-cluster \
--release-channel=RELEASE_CHANNEL \
--cluster-version=CLUSTER_VERSION \
--location=us-central1
Ersetzen Sie Folgendes:
RELEASE_CHANNEL
: der Release-Channel für Ihren Cluster. Mussrapid
,regular
oderstable
sein. Wählen Sie einen Kanal mit der GKE-Version 1.28.3-gke.1203000 oder höher aus, um L4-GPUs zu verwenden. Informationen zu den in einem bestimmten Kanal verfügbaren Versionen finden Sie unter Standardversion und verfügbare Versionen für Release-Versionen ansehen.CLUSTER_VERSION
ist die zu verwendende GKE-Version. Es muss1.28.3-gke.1203000
oder höher sein.
Dieser Vorgang kann mehrere Minuten dauern.
Artifact Registry-Repository erstellen
Erstellen Sie ein neues Artifact Registry-Standard-Repository im Docker-Format in derselben Region wie Ihr Cluster:
gcloud artifacts repositories create models \ --repository-format=docker \ --location=us-central1 \ --description="Repo for T5 serving image"
Prüfen Sie den Repository-Namen:
gcloud artifacts repositories describe models \ --location=us-central1
Die Ausgabe sieht in etwa so aus:
Encryption: Google-managed key Repository Size: 0.000MB createTime: '2023-06-14T15:48:35.267196Z' description: Repo for T5 serving image format: DOCKER mode: STANDARD_REPOSITORY name: projects/PROJECT_ID/locations/us-central1/repositories/models updateTime: '2023-06-14T15:48:35.267196Z'
Modell verpacken
In diesem Abschnitt verpacken Sie das Modell und das Bereitstellungsframework mit Cloud Build in einem einzigen Container-Image und übertragen das resultierende Image in das Artifact Registry-Repository.
Prüfen Sie das Dockerfile für das Container-Image:
Dieses Dockerfile definiert den folgenden mehrstufigen Build-Prozess:
- Laden Sie die Modellartefakte aus dem Hugging Face-Repository herunter.
- Verpacken Sie das Modell mit dem Tool PyTorch Serving Archive. Dadurch wird eine Modellarchivdatei (.mar) erstellt, mit der der Inferenzserver das Modell lädt.
- Erstellen Sie das endgültige Image mit PyTorch Serve.
Erstellen und übertragen Sie das Image mit Cloud Build:
gcloud builds submit model/ \ --region=us-central1 \ --config=model/cloudbuild.yaml \ --substitutions=_LOCATION=us-central1,_MACHINE=gpu,_MODEL_NAME=t5-small,_MODEL_VERSION=1.0
Der Build-Prozess dauert einige Minuten. Wenn Sie ein größeres Modell als
t5-small
verwenden, kann der Build-Prozess erheblich länger dauern.Prüfen Sie, ob sich das Image im Repository befindet:
gcloud artifacts docker images list us-central1-docker.pkg.dev/PROJECT_ID/models
Ersetzen Sie
PROJECT_ID
durch Ihre Google CloudProjekt-ID.Die Ausgabe sieht etwa so aus:
IMAGE DIGEST CREATE_TIME UPDATE_TIME us-central1-docker.pkg.dev/PROJECT_ID/models/t5-small sha256:0cd... 2023-06-14T12:06:38 2023-06-14T12:06:38
Verpacktes Modell in GKE bereitstellen
In dieser Anleitung werden Kubernetes-Deployments zum Bereitstellen des Images verwendet. Ein Deployment ist ein Kubernetes API-Objekt, mit dem Sie mehrere Replikate von Pods ausführen können, die auf die Knoten in einem Cluster verteilt sind.
Passen Sie das Kubernetes-Manifest im Beispiel-Repository an Ihre Umgebung an.
Überprüfen Sie das Manifest für die Inferenzarbeitslast:
Ersetzen Sie
PROJECT_ID
durch Ihre Google CloudProjekt-ID:sed -i "s/PROJECT_ID/PROJECT_ID/g" "kubernetes/serving-gpu.yaml"
So wird sichergestellt, dass der Pfad zum Container-Image in der Bereitstellungsspezifikation mit dem Pfad zum T5-Modell-Image in Artifact Registry übereinstimmt.
Erstellen Sie die Kubernetes-Ressourcen:
kubectl create -f kubernetes/serving-gpu.yaml
So prüfen Sie, ob das Modell bereitgestellt wurde:
Rufen Sie den Status der Bereitstellung und des Dienstes ab:
kubectl get -f kubernetes/serving-gpu.yaml
Warten Sie, bis in der Ausgabe bereite Pods angezeigt werden, z. B. so: Je nach Größe des Images kann der erste Image-Pull einige Minuten dauern.
NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/t5-inference 1/1 1 0 66s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/t5-inference ClusterIP 10.48.131.86 <none> 8080/TCP,8081/TCP,8082/TCP 66s
Öffnen Sie einen lokalen Port für den
t5-inference
-Dienst:kubectl port-forward svc/t5-inference 8080
Öffnen Sie ein neues Terminalfenster und senden Sie eine Testanfrage an den Dienst:
curl -v -X POST -H 'Content-Type: application/json' -d '{"text": "this is a test sentence", "from": "en", "to": "fr"}' "http://localhost:8080/predictions/t5-small/1.0"
Wenn die Testanfrage fehlschlägt und die Pod-Verbindung geschlossen wird, prüfen Sie die Protokolle:
kubectl logs deployments/t5-inference
Wenn die Ausgabe in etwa so aussieht, konnte TorchServe einige Modellabhängigkeiten nicht installieren:
org.pytorch.serve.archive.model.ModelException: Custom pip package installation failed for t5-small
Starten Sie die Bereitstellung neu, um das Problem zu beheben:
kubectl rollout restart deployment t5-inference
Der Deployment-Controller erstellt einen neuen Pod. Wiederholen Sie die vorherigen Schritte, um einen Port auf dem neuen Pod zu öffnen.
Über die Webanwendung auf das bereitgestellte Modell zugreifen
So greifen Sie mit der Fast Dash-Webanwendung auf das bereitgestellte Modell zu:
Erstellen Sie die Webanwendung „Fast Dash“ als Container-Image in Artifact Registry und übertragen Sie es per Push:
gcloud builds submit client-app/ \ --region=us-central1 \ --config=client-app/cloudbuild.yaml
Öffnen Sie
kubernetes/application.yaml
in einem Texteditor und ersetzen SiePROJECT_ID
im Feldimage:
durch Ihre Projekt-ID. Alternativ können Sie den folgenden Befehl ausführen:sed -i "s/PROJECT_ID/PROJECT_ID/g" "kubernetes/application.yaml"
Erstellen Sie die Kubernetes-Ressourcen:
kubectl create -f kubernetes/application.yaml
Die Bereitstellung der Bereitstellung und des Dienstes kann einige Zeit dauern.
Führen Sie zum Prüfen des Status den folgenden Befehl aus:
kubectl get -f kubernetes/application.yaml
Warten Sie, bis in der Ausgabe bereite Pods angezeigt werden, z. B.:
NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/fastdash 1/1 1 0 1m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fastdash NodePort 203.0.113.12 <none> 8050/TCP 1m
Die Webanwendung wird jetzt ausgeführt, obwohl sie nicht über eine externe IP-Adresse freigegeben ist. Öffnen Sie einen lokalen Port, um auf die Webanwendung zuzugreifen:
kubectl port-forward service/fastdash 8050
Öffnen Sie in einem Browser die Weboberfläche:
- Wenn Sie eine lokale Shell verwenden, öffnen Sie einen Browser und rufen Sie http://127.0.0.1:8050 auf.
- Wenn Sie Cloud Shell verwenden, klicken Sie auf Webvorschau und dann auf Port ändern. Gib Port
8050
an.
Um eine Anfrage an das T5-Modell zu senden, geben Sie in der Weboberfläche Werte in den Feldern TEXT, FROM LANG und TO LANG an. und klicken Sie auf Senden. Eine Liste der verfügbaren Sprachen finden Sie in der T5-Dokumentation.
Autoscaling für das Modell aktivieren
In diesem Abschnitt erfahren Sie, wie Sie die automatische Skalierung für das Modell basierend auf Messwerten aus Google Cloud Managed Service for Prometheus aktivieren. Gehen Sie dazu so vor:
- Stackdriver-Adapter für benutzerdefinierte Messwerte installieren
- PodMonitoring- und HorizontalPodAutoscaling-Konfigurationen anwenden
Google Cloud Managed Service for Prometheus ist in Autopilot-Clustern mit Version 1.25 und höher standardmäßig aktiviert.
Stackdriver-Adapter für benutzerdefinierte Messwerte installieren
Mit diesem Adapter kann Ihr Cluster Messwerte von Prometheus verwenden, um Kubernetes-Skalierungsentscheidungen zu treffen.
Stellen Sie den Adapter bereit:
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
Erstellen Sie ein IAM-Dienstkonto für den Adapter:
gcloud iam service-accounts create monitoring-viewer
Weisen Sie dem IAM-Dienstkonto die Rolle
monitoring.viewer
für das Projekt und die Rolleiam.workloadIdentityUser
zu:gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:monitoring-viewer@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/monitoring.viewer gcloud iam service-accounts add-iam-policy-binding monitoring-viewer@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[custom-metrics/custom-metrics-stackdriver-adapter]"
Ersetzen Sie
PROJECT_ID
durch Ihre Google CloudProjekt-ID.Annotieren Sie das Kubernetes-Dienstkonto des Adapters, damit es die Identität des IAM-Dienstkontos übernehmen kann:
kubectl annotate serviceaccount custom-metrics-stackdriver-adapter \ --namespace custom-metrics \ iam.gke.io/gcp-service-account=monitoring-viewer@PROJECT_ID.iam.gserviceaccount.com
Starten Sie den Adapter neu, um die Änderungen zu übernehmen:
kubectl rollout restart deployment custom-metrics-stackdriver-adapter \ --namespace=custom-metrics
PodMonitoring- und HorizontalPodAutoscaling-Konfigurationen anwenden
PodMonitoring ist eine benutzerdefinierte Ressource von Google Cloud Managed Service for Prometheus, die die Aufnahme von Messwerten und die Ziel-Extraktion in einem bestimmten Namespace ermöglicht.
Stellen Sie die PodMonitoring-Ressource im selben Namespace wie die TorchServe-Bereitstellung bereit:
kubectl apply -f kubernetes/pod-monitoring.yaml
Sehen Sie sich das HorizontalPodAutoscaler-Manifest an:
Der HorizontalPodAutoscaler skaliert die Anzahl der T5-Modell-Pods basierend auf der kumulativen Dauer der Anfragewarteschlange. Das Autoscaling basiert auf dem Messwert
ts_queue_latency_microseconds
, der die kumulative Warteschlangendauer in Mikrosekunden angibt.Erstellen Sie den HorizontalPodAutoscaler:
kubectl apply -f kubernetes/hpa.yaml
Autoscaling mit einem Lastgenerator prüfen
Um die Autoscaling-Konfiguration zu testen, generieren Sie eine Auslastung für die Bereitstellungsanwendung. In dieser Anleitung wird ein Locust-Lastgenerator verwendet, um Anfragen an den Vorhersageendpunkt für das Modell zu senden.
Erstellen Sie den Load Generator:
kubectl apply -f kubernetes/loadgenerator.yaml
Warten Sie, bis die Pods des Load Generators bereit sind.
Machen Sie die Weboberfläche des Lastgenerators lokal verfügbar:
kubectl port-forward svc/loadgenerator 8080
Wenn eine Fehlermeldung angezeigt wird, versuchen Sie es noch einmal, wenn der Pod ausgeführt wird.
Öffnen Sie in einem Browser die Weboberfläche des Lastgenerators:
- Wenn Sie eine lokale Shell verwenden, öffnen Sie einen Browser und rufen Sie http://127.0.0.1:8080 auf.
- Wenn Sie Cloud Shell verwenden, klicken Sie auf Webvorschau und dann auf Port ändern. Geben Sie Port
8080
ein.
Klicken Sie auf den Tab Diagramme, um die Leistung im Zeitverlauf zu beobachten.
Öffnen Sie ein neues Terminalfenster und beobachten Sie die Anzahl der Replikate Ihrer horizontalen Pod-Autoscalings:
kubectl get hpa -w
Die Anzahl der Replikate erhöht sich, wenn die Last zunimmt. Das Hochskalieren kann etwa zehn Minuten dauern. Wenn neue Replikate gestartet werden, steigt die Anzahl der erfolgreichen Anfragen im Locust-Diagramm.
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE t5-inference Deployment/t5-inference 71352001470m/7M 1 5 1 2m11s
Empfehlungen
- Erstellen Sie Ihr Modell mit derselben Version des Basis-Docker-Images, die Sie für die Bereitstellung verwenden.
- Wenn Ihr Modell spezielle Paketabhängigkeiten hat oder die Größe Ihrer Abhängigkeiten groß ist, erstellen Sie eine benutzerdefinierte Version Ihres Basis-Docker-Images.
- Beobachten Sie die Strukturversion Ihrer Modellabhängigkeitspakete. Achten Sie darauf, dass die Versionen Ihrer Paketabhängigkeiten zueinander passen. Panda 2.0.3 unterstützt beispielsweise NumPy 1.20.3 und höher.
- GPU-intensive Modelle auf GPU-Knoten und CPU-intensive Modelle auf der CPU ausführen. Dies kann die Stabilität der Modellbereitstellung verbessern und dafür sorgen, dass Sie die Knotenressourcen effizient nutzen.
Modellleistung beobachten
Sie können die Modellleistung mit der TorchServe-Dashboard-Integration in Cloud Monitoring beobachten. In diesem Dashboard können Sie wichtige Leistungsmesswerte wie Tokendurchsatz, Anfragelatenz und Fehlerraten abrufen.
Wenn Sie das TorchServe-Dashboard verwenden möchten, müssen Sie Google Cloud Managed Service for Prometheus in Ihrem GKE-Cluster aktivieren. Dieser Dienst erfasst die Messwerte von TorchServe. TorchServe stellt standardmäßig Messwerte im Prometheus-Format bereit. Sie müssen keinen zusätzlichen Exporter installieren.
Sie können die Messwerte dann über das TorchServe-Dashboard aufrufen. Informationen zur Verwendung von Google Cloud Managed Service for Prometheus zum Erfassen von Messwerten aus Ihrem Modell finden Sie in der Cloud Monitoring-Dokumentation unter TorchServe.Bereinigen
Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.
Projekt löschen
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Einzelne Ressourcen löschen
Löschen Sie die Kubernetes-Ressourcen:
kubectl delete -f kubernetes/loadgenerator.yaml kubectl delete -f kubernetes/hpa.yaml kubectl delete -f kubernetes/pod-monitoring.yaml kubectl delete -f kubernetes/application.yaml kubectl delete -f kubernetes/serving-gpu.yaml kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
Löschen Sie den GKE-Cluster:
gcloud container clusters delete "ml-cluster" \ --location="us-central1" --quiet
Löschen Sie das IAM-Dienstkonto und die IAM-Richtlinienbindungen:
gcloud projects remove-iam-policy-binding PROJECT_ID \ --member "serviceAccount:monitoring-viewer@PROJECT_ID.iam.gserviceaccount.com" \ --role roles/monitoring.viewer gcloud iam service-accounts remove-iam-policy-binding monitoring-viewer@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[custom-metrics/custom-metrics-stackdriver-adapter]" gcloud iam service-accounts delete monitoring-viewer
Löschen Sie die Images in Artifact Registry. Optional können Sie das gesamte Repository löschen. Eine Anleitung finden Sie in der Artifact Registry-Dokumentation unter Images löschen.
Komponenten – Übersicht
In diesem Abschnitt werden die in dieser Anleitung verwendeten Komponenten beschrieben, z. B. das Modell, die Webanwendung, das Framework und der Cluster.
T5-Modell
In dieser Anleitung wird ein vortrainiertes mehrsprachiges T5-Modell verwendet. T5 ist ein Text-zu-Text-Transformer, der Text von einer Sprache in eine andere konvertiert. Bei T5 sind Eingaben und Ausgaben immer Textstrings, im Gegensatz zu BERT-Modellen, die nur ein Klassenlabel oder einen Teil der Eingabe ausgeben können. Das T5-Modell kann auch für Aufgaben wie Zusammenfassung, Fragen und Antworten oder Textklassifizierung verwendet werden. Das Modell wird mit einer großen Menge an Text aus dem Colossal Clean Crawled Corpus (C4) und Wiki-DPR trainiert.
Weitere Informationen finden Sie in der Dokumentation zum T5-Modell.
Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li und Peter J. Liu stellte das T5-Modell in Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer vor, veröffentlicht im Journal of Machine Learning Research.
Das T5-Modell unterstützt verschiedene Modellgrößen mit unterschiedlichen Komplexitätsgraden, die für bestimmte Anwendungsfälle geeignet sind. In dieser Anleitung wird die Standardgröße t5-small
verwendet. Sie können aber auch eine andere Größe auswählen. Die folgenden T5-Größen werden unter der Apache 2.0-Lizenz vertrieben:
t5-small
: 60 Millionen Parametert5-base
: 220 Millionen Parametert5-large
: 770 Millionen Parameter. 3 GB Download.t5-3b
: 3 Milliarden Parameter. 11 GB Download.t5-11b
: 11 Milliarden Parameter. 45 GB Download.
Weitere verfügbare T5-Modelle finden Sie im Hugging Face-Repository.
TorchServe
TorchServe ist ein flexibles Tool zum Bereitstellen von PyTorch-Modellen. Sie bietet standardmäßig Unterstützung für alle gängigen Deep-Learning-Frameworks wie PyTorch, TensorFlow und ONNX. TorchServe kann zum Bereitstellen von Modellen in der Produktion oder für schnelles Prototyping und Experimente verwendet werden.
Nächste Schritte
- LLM mit mehreren GPUs bereitstellen
- Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center