Skaliertes Ausführen einer TensorFlow-Inferenz mit TensorRT 5- und NVIDIA T4-GPUs

In dieser Anleitung erfahren Sie, wie Sie eine Inferenz mit NVIDIA TensorRT 5- und T4-GPUs in großem Umfang ausführen. NVIDIA TensorRT™ ist eine Plattform für hochleistungsfähige Deep-Learning-Inferenz. Sie beinhaltet einen Deep-Learning-Inferenzoptimierer und eine Laufzeit mit niedrigen Latenzzeiten und einem hohen Durchsatz für Deep-Learning-Inferenzanwendungen.

In dieser Anleitung richten Sie einen Mehrzonencluster für die Ausführung einer Inferenz mit einer Gruppe ein, die automatisch auf Basis der GPU-Nutzung skaliert wird.

Übersicht

In dieser Anleitung wird Folgendes bereitgestellt:

  • Eine Referenzarchitektur zur Implementierung eines skalierbaren Inferenzsystems für maschinelles Lernen in Google Cloud, das für eine Entwicklungsumgebung geeignet ist. Da Infrastruktur- und Sicherheitsanforderungen variieren, können Sie die in dieser Anleitung beschriebenen Konfigurationen entsprechend anpassen.
  • Ein GitHub-Repository mit Skripts, die Sie in dieser Anleitung verwenden können, um das TensorFlow-Modell und andere erforderliche Komponenten zu installieren.
  • Anleitungen zum Quantisieren des TensorFlow-Modells mit TensorRT, zum Bereitstellen von Skripts und zum Bereitstellen der Referenzarchitektur.
  • Anleitung zum Konfigurieren von Cloud Load Balancing

Nach Abschluss dieser Anleitung haben Sie ein vorab trainiertes, quantisiertes Modell in Cloud Storage und zwei geclusterte Instanzgruppen in Compute Engine in verschiedenen Regionen. Der Webtraffic wird über Cloud Load Balancing zu den Instanzen weitergeleitet. Diese Architektur wird im folgenden Diagramm dargestellt.

In dieser Anleitung verwendete Architektur

Ziele

  • Sie beginnen mit einer vorab trainierten Grafik.
  • Sie optimieren das Modell mit TensorRT und stellen fest, wie sich verschiedene Optimierungen auf die Geschwindigkeit des Modells auswirken.
  • Sie erstellen nach Fertigstellen des Modells einen Cluster auf Basis der Deep-Learning-VM der Compute Engine, die mit bereits vorinstalliertem TensorFlow, TensorFlow Serving und TensorRT 5 bereitgestellt werden.

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

  • Compute Engine
  • Persistent Disk
  • Cloud Storage
  • Netzwerk
  • NVIDIA T4-GPU

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Vorbereitung

  1. Rufen Sie in der Cloud Console die Seite für die Projektauswahl auf.

    Zur Projektauswahl

  2. Wählen Sie ein Cloud-Projekt aus oder erstellen Sie eines.

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

  4. Compute Engine and Cloud Logging APIs aktivieren.

    Aktivieren Sie die APIs

  5. Achten Sie auf ein ausreichendes GPU-Kontingent zum Erstellen von VMs.

Nach Abschluss dieser Anleitung können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Umgebung vorbereiten

In diesem Abschnitt legen Sie Standardeinstellungen für Werte fest, die in der gesamten Anleitung verwendet werden, zum Beispiel Region und Zone. In dieser Anleitung verwenden Sie us-central1 als Standardregion und us-central1-b als Standardzone.

Außerdem erstellen Sie eine Datei mit allen Einstellungen. Damit können die Variablen automatisch geladen werden, falls Sie Cloud Shell noch einmal öffnen und die Einstellungen neu initialisieren müssen.

  1. Öffnen Sie Cloud Shell:

    Cloud Shell ÖFFNEN

  2. Legen Sie die Standardregion und -zone fest.

    gcloud compute project-info add-metadata \
        --metadata google-compute-default-region=us-central1,google-compute-default-zone=us-central1-a
    
  3. Initialisieren Sie die Shell neu:

    gcloud init --console-only
    
  4. Drücken Sie bei den ersten drei Fragen 1 und geben Sie dann bei der letzten Frage die Projekt-ID ein.

Modell mit TensorRT optimieren

  1. Erstellen Sie in Cloud Shell eine Instanz für die Modellvorbereitung:

    export IMAGE_FAMILY="tf-latest-cu100"
    export INSTANCE_NAME="model-prep"
    
    gcloud compute instances create $INSTANCE_NAME \
        --image-family=$IMAGE_FAMILY \
        --machine-type=n1-standard-8 \
        --image-project=deeplearning-platform-release \
        --maintenance-policy=TERMINATE \
        --accelerator="type=nvidia-tesla-t4,count=1" \
        --metadata="install-nvidia-driver=True"
    

    Eine GPU ist mehr als ausreichend, damit Sie verschiedene TensorRT-Optimierungsmodi vergleichen und ein Gefühl dafür bekommen können, wie schnell eine einzelne GPU sein kann.

  2. Nachdem die VM-Instanz erstellt wurde, stellen Sie mit ssh eine Verbindung zur VM her.

  3. Laden Sie in der Instanz das Modell resnetv2 aus dem offiziellen TensorFlow-Repository herunter, damit Sie die TensorRT-Optimierung testen können:

    wget -q http://download.tensorflow.org/models/official/resnetv2_imagenet_frozen_graph.pb
    

TensorRT kann die Inferenz beschleunigen, zusätzliche Verbesserungen werden jedoch durch Quantisierung erreicht. Die lineare Modellquantisierung konvertiert Gewichtungen und Aktivierungen von Gleitkomma- zu Ganzzahlen. Wenn die anfängliche Gewichtung des Modells beispielsweise FP32 ist (32-Bit-Gleitkommazahl), können Sie durch Verringerung der Genauigkeit INT8 verwenden. Die Quantisierung hat jedoch Auswirkungen: Durch die Reduzierung der Speicherdarstellung können Sie die Genauigkeit des Modells minimal reduzieren. Der Übergang von FP32 zu FP16 bleibt jedoch praktisch ohne negative Auswirkungen.

Wie finden Sie den richtigen Kompromiss zwischen Geschwindigkeit (Genauigkeit der Gewichtungen) und Genauigkeit des Modells? Es gibt dafür bereits vorhandenen Code. Dieser Code kann die Genauigkeit im Verhältnis zur Geschwindigkeit und zu anderen Messwerten messen. Der Test ist auf Bilderkennungsmodelle beschränkt. Es ist jedoch nicht schwierig, einen auf diesem Code basierenden benutzerdefinierten Test zu implementieren.

  1. Laden Sie in Cloud Shell einen benutzerdefinierten Test herunter und implementieren Sie ihn:

    git clone https://github.com/tensorflow/models.git
    cd models
    git checkout f0e10716160cd048618ccdd4b6e18336223a172f
    touch research/__init__.py
    touch research/tensorrt/__init__.py
    cp research/tensorrt/labellist.json .
    cp research/tensorrt/image.jpg .
    
  2. Bereiten Sie den Test für die Ausführung vor:

    python -m research.tensorrt.tensorrt \
        --frozen_graph=$HOME/resnetv2_imagenet_frozen_graph.pb \
        --image_file=$HOME/models/image.jpg \
        --native --fp32 --fp16 --int8 \
        --output_dir=$HOME
    

    Der Test erfordert eine fixierte Grafik (das zuvor heruntergeladene Modell resnetv2) und Argumente für die verschiedenen zu testenden Quantisierungsmodi. Der Abschluss dieses Befehls dauert einige Zeit.

    Wenn die Ausführung abgeschlossen ist, zeigt die daraus resultierende Ausgabe einen Vergleich der Inferenzergebnisse der verschiedenen Versionen der Grafik:

    Screenshot: Vergleich der Inferenzergebnisse verschiedener Versionen der Grafik

    Die Ergebnisse von FP32 und FP16 sind identisch und zeigen die gleiche Genauigkeit. Wenn Sie also mit TensorRT arbeiten möchten, können Sie auf jeden Fall sofort mit FP16 beginnen. Im Gegensatz dazu zeigt INT8 etwas weniger genaue Ergebnisse.

  3. Lassen Sie die Werte für die Genauigkeit anzeigen:

    cat $HOME/log.txt
    

    Dieser Befehl erzeugt folgende Ausgabe:

    Log für skalierte Inferenz

TensorRT 5 zeigt die folgenden Ergebnisse, alle im Vergleich mit "native":

  • Bei FP32 verbesserte sich der Durchsatz um ca. 34 % von 319,1 fps auf 428,2 fps.
  • Bei FP16 verbesserte sich der Durchsatz um ca. 207 % von 319,1 fps auf 979,6 fps.
  • Bei INT8 verbesserte sich der Durchsatz um ca. 376 % von 319,1 fps auf 1519,5 fps.

Folgendes können Sie aus diesen Ergebnissen lernen:

  • Der Übergang von nativ zu TensorRT wirkt sich auf die Unsicherheit aus. Wenn Sie jedoch mit den geringen Auswirkungen einverstanden sind, können Sie wahrscheinlich direkt zu FP16 wechseln.
  • INT8 ist zwar sehr schnell, aber die Auswirkungen sind merklich ausgeprägter.

Im nächsten Abschnitt wird das INT8-Modell verwendet.

Benutzerdefiniertes Modell nach TensorRT konvertieren

Zum Konvertieren eines Modells in einen TensorRT-Graphen benötigen Sie ein SavedModel.

  1. Laden Sie in Cloud Shell das folgende vorab trainierte SavedModel herunter:

    wget http://download.tensorflow.org/models/official/20181001_resnet/savedmodels/resnet_v2_fp32_savedmodel_NCHW.tar.gz
    tar -xzvf resnet_v2_fp32_savedmodel_NCHW.tar.gz
    
  2. Erstellen Sie ein Python-Skript, das das fixierte Modell in eine TensorRT-Grafik konvertiert:

    cat <<EOF > convert_to_rt.py
    import tensorflow.contrib.tensorrt as trt
    import argparse
    
    parser = argparse.ArgumentParser(description="Converts TF SavedModel to the TensorRT enabled graph.")
    
    parser.add_argument("--input_model_dir", required=True)
    parser.add_argument("--output_model_dir", required=True)
    parser.add_argument("--batch_size", type=int, required=True)
    parser.add_argument("--precision_mode", choices=["FP32", "FP16", "INT8"], required=True)
    
    args = parser.parse_args()
    
    trt.create_inference_graph(
        None, None, max_batch_size=args.batch_size,
        input_saved_model_dir=args.input_model_dir,
        output_saved_model_dir=args.output_model_dir,
        precision_mode=args.precision_mode)
    EOF
    
  3. Konvertieren Sie das Modell in die TensorRT-Grafik:

    python ./convert_to_rt.py \
        --input_model_dir=$HOME/resnet_v2_fp32_savedmodel_NCHW/1538687196 \
        --output_model_dir=$HOME/resnet_v2_int8_NCHW/00001 \
        --batch_size=128 \
        --precision_mode="INT8"
    

    Sie haben nun ein INT8-Modell im Ordner $HOME/resnet_v2_int8_NCHW/00001.

  4. Führen Sie eine Inferenz aus, um zu prüfen, ob alles funktioniert:

    tensorflow_model_server --model_base_path=$HOME/resnet_v2_int8_NCHW/ --rest_api_port=8888
    
  5. Senden Sie die folgende Beispieleingabe, um zu prüfen, ob es funktioniert:

    curl -X POST localhost:8888/v1/models/default:predict -d '{"instances": [[[[1,1,1]]]]}'
    
  6. Wenn Sie Ergebnisse von diesem curl-Befehl sehen, beenden Sie die ausgeführte Inferenz durch Drücken von Strg+C.

  7. Damit Sie das optimierte Modell in Ihrem Cluster verwenden können, laden Sie das Modell in Cloud Storage hoch und ersetzen Sie [GCS_PATH] durch den Namen des Cloud Storage-Buckets:

    tar -zcvf model.tar.gz ./resnet_v2_int8_NCHW/
    export GCS_PATH=[GCS_PATH]
    gsutil cp model.tar.gz $GCS_PATH
    

    Wenn Sie dieses Modell das nächste Mal verwenden möchten, müssen Sie nicht diesen gesamten Vorgang wiederholen. Stattdessen können Sie die fixierte INT8-Grafik im Cloud Storage-Bucket verwenden:

    gs://solutions-public-assets/tensorrt-t4-gpu/model.tar.gz
    

Cluster einrichten

Da Sie jetzt ein Modell in Cloud Storage haben, können Sie einen Cluster erstellen. Als Erstes erstellen Sie dazu eine VM-Vorlage. Der Cluster verwendet die VM-Vorlage zum Erstellen neuer Instanzen.

  1. Laden Sie in Cloud Shell den zum Einrichten des Clusters benötigten Code herunter:

    git clone https://github.com/GoogleCloudPlatform/tensorflow-inference-tensorrt5-t4-gpu.git
    
  2. Erstellen Sie die VM-Vorlage und ersetzen Sie [PROJECT_NAME] durch Ihren Projektnamen:

    export PROJECT_NAME=[PROJECT_NAME]
    export INSTANCE_TEMPLATE_NAME="tf-inference-template"
    export IMAGE_FAMILY="tf-latest-cu100"
    
    gcloud beta compute --project=$PROJECT_NAME instance-templates create $INSTANCE_TEMPLATE_NAME \
        --machine-type=n1-standard-16 \
        --maintenance-policy=TERMINATE \
        --accelerator=type=nvidia-tesla-t4,count=4 \
        --min-cpu-platform=Intel\ Skylake \
        --tags=http-server,https-server \
        --image-family=$IMAGE_FAMILY \
        --image-project=deeplearning-platform-release \
        --boot-disk-size=100GB \
        --boot-disk-type=pd-ssd \
        --boot-disk-device-name=$INSTANCE_TEMPLATE_NAME \
        --metadata startup-script-url=gs://solutions-public-assets/tensorrt-t4-gpu/start_agent_and_inf_server.sh
    

    Mit dem Parameter metadata wird ein Startskript angegeben, das in jeder durch die VM-Vorlage erstellten Instanz installiert ist. Das Startskript führt die folgenden Aufgaben aus, wenn die VM-Instanz gestartet wird:

    • NVIDIA-Treiber installieren
    • Monitoring-Agent zur Überwachung der GPU-Nutzung installieren
    • Modell herunterladen
    • Inferenzdienst starten

    Wenn die Vorlage fertig ist, können Sie die verwaltete Instanzgruppe erstellen. Die Gruppe ist keine Skalierungsgruppe und es werden keine Systemdiagnosen durchgeführt. Sie erstellen eine Gruppe mit nur der einen Garantie, dass zwei Instanzen in bestimmten Zonen ausgeführt werden.

  3. Erstellen Sie die verwaltete Instanzgruppe:

    gcloud compute instance-groups managed create $INSTANCE_GROUP_NAME \
        --template $INSTANCE_TEMPLATE_NAME \
        --base-instance-name deeplearning-instances \
        --size 2 \
        --zones us-central1-a,us-central1-b
    

    Der Wert INSTANCE_TEMPLATE_NAME ist der Name der Instanz, den Sie in einem vorherigen Schritt festgelegt haben. Wählen Sie Zonen anhand der Verfügbarkeit von GPUs (nicht alle GPUs sind in allen Zonen verfügbar) und Ihrer Kontingente aus.

    Das Erstellen der Gruppe dauert einige Zeit.

  4. Überwachen Sie den Fortschritt mit dem folgenden Befehl:

    gcloud compute instance-groups managed list-instances $INSTANCE_GROUP_NAME --region us-central1
    

    Die Ausgabe sieht in etwa so aus:

    Während der Erstellung der Gruppe

    Wenn die Erstellung abgeschlossen ist, erhalten Sie in etwa folgende Ausgabe:

    Nach der Erstellung der Gruppe

  5. Öffnen Sie in der Cloud Console die Seite "Monitoring".

    Zur Seite "Monitoring"

  6. Achten Sie darauf, dass Sie sich im richtigen Projektarbeitsbereich befinden. Dieser wird in der oberen linken Ecke angezeigt. Wenn Sie diese Seite zum ersten Mal besuchen, müssen Sie einen neuen Arbeitsbereich erstellen.

  7. Wählen Sie auf der Seite Metrics Explorer für Ressourcentyp GCE VM Instance und für Messwert custom/gpu_utilization aus:

    Screenshot: Seite

    Wenn Daten eingehen, sehen Sie in etwa Folgendes:

    Messwertgrafik zeigt keine Nutzung

  8. Aktivieren Sie in Cloud Shell das Autoscaling für Ihre Gruppe:

    gcloud compute instance-groups managed set-autoscaling $INSTANCE_GROUP_NAME \
        --custom-metric-utilization metric=custom.googleapis.com/gpu_utilization,utilization-target-type=GAUGE,utilization-target=85 \
        --max-num-replicas 4 \
        --cool-down-period 360 \
        --region us-central1
    

    Der wichtige Teil hier ist der Pfad für die Auslastung: custom.googleapis.com/gpu_utilization. Dies ist der vollständige Pfad zum Messwert. Da Sie eine Zielauslastung von 85 angegeben haben, wird immer eine neue Instanz in der Gruppe erstellt, wenn die GPU-Auslastung 85 % erreicht.

Autoscaling testen

Führen Sie folgende Schritte aus, um das im vorherigen Abschnitt eingerichtete Autoscaling zu testen:

  • Stellen Sie mit SSH eine Verbindung zu einer der Deep-Learning-GPU-Instanzen her.
  • Belasten Sie alle GPUs zu 100 %.
  • Beobachten Sie, wie sich die Autoscaling-Gruppe durch das Erstellen einer weiteren Instanz vergrößert.

  1. Stellen Sie über ssh eine Verbindung zur Instanz her.
  2. Lasten Sie die GPU 600 Sekunden lang zu 100 % aus:

    git clone https://github.com/GoogleCloudPlatform/tensorflow-inference-tensorrt5-t4-gpu.git
    cd tensorflow-inference-tensorrt5-t4-gpu
    git submodule update --init --recursive
    cd third_party/gpu-burn
    make
    ./gpu_burn 600 > /dev/null &
    

    Achten Sie in der Cloud Console auf die Aktivität auf der Seite Metrics Explorer:

    Screenshot: Aktivitätsspitze auf der Seite

  3. Erstellen Sie die zweite Instanz.

  4. Wechseln Sie zur Seite Google Compute Engine > Instanzgruppen > Monitoring und beobachten Sie die Aktivität:

    Screenshot: Höhere Aktivitätsspitze beim Monitoring

    An diesem Punkt versucht das Autoscaling erfolglos, so viele Instanzen wie möglich einzurichten, um die Last zu reduzieren. Folgendes passiert:

    Viele Instanzen werden gestartet

  5. Beenden Sie das Starten von Instanzen und beobachten Sie, wie die Aktivität abnimmt.

Folgendes haben Sie nun eingerichtet:

  • Ein trainiertes Modell, optimiert mit TensorRT 5 (INT8)
  • Eine verwaltete Gruppe von Deep-Learning-Instanzen
  • Autoscaling basierend auf der GPU-Nutzung

Load-Balancer erstellen

Der letzte Schritt ist das Erstellen eines Load-Balancers vor den Instanzen.

  1. Erstellen Sie in Cloud Shell Systemdiagnosen, damit Sie feststellen können, ob ein bestimmter Host im Back-End den Traffic verarbeiten kann:

    gcloud compute health-checks create http $HEALTH_CHECK_NAME \
        --request-path /v1/models/default \
        --port 8888
    
  2. Konfigurieren Sie die benannten Ports der Instanzgruppe, damit der Load-Balancer Inferenzanfragen über Port 80 an den über Port 8888 bereitgestellten Inferenzdienst weiterleiten kann:

    gcloud compute instance-groups set-named-ports $INSTANCE_GROUP_NAME \
        --named-ports http:8888 \
        --region us-central1
    
  3. Erstellen Sie einen Back-End-Dienst.

    export WEB_BACKED_SERVICE_NAME="tensorflow-backend"
    
    gcloud compute backend-services create $WEB_BACKED_SERVICE_NAME \
        --protocol HTTP \
        --health-checks $HEALTH_CHECK_NAME \
        --global
    

    Ein Back-End-Dienst ist eine Instanzgruppe mit Systemdiagnose.

  4. Fügen Sie die Instanzgruppe dem neuen Back-End-Dienst hinzu:

    gcloud compute backend-services add-backend $WEB_BACKED_SERVICE_NAME \
        --balancing-mode UTILIZATION \
        --max-utilization 0.8 \
        --capacity-scaler 1 \
        --instance-group $INSTANCE_GROUP_NAME \
        --instance-group-region us-central1 \
        --global
    
  5. Teilen Sie dem Load-Balancer mit, welche URL an den Back-End-Dienst weitergeleitet werden soll:

    export WEB_MAP_NAME="map-all"
    
    gcloud compute url-maps create $WEB_MAP_NAME \
        --default-service $WEB_BACKED_SERVICE_NAME
    
  6. Erstellen Sie den Load-Balancer:

    export LB_NAME="tf-lb"
    
    gcloud compute target-http-proxies create $LB_NAME \
        --url-map $WEB_MAP_NAME
    
  7. Erstellen Sie eine externe IP-Adresse für den Load-Balancer:

    export IP4_NAME="lb-ip4"
    
    gcloud compute addresses create $IP4_NAME \
        --ip-version=IPV4 \
        --global
    
  8. Prüfen Sie, ob die IP-Adresse zugewiesen wurde:

    gcloud compute addresses list
    
  9. Prüfen Sie die Weiterleitungsregel, die Google Cloud verwendet, um alle Anfragen von der öffentlichen IP-Adresse an den Load-Balancer weiterzuleiten.

    export IP=$(gcloud compute addresses list | grep ${IP4_NAME} | awk '{print $2}')
    export FORWARDING_RULE="lb-fwd-rule"
    
    gcloud compute forwarding-rules create $FORWARDING_RULE \
        --address $IP \
        --global \
        --target-http-proxy $LB_NAME \
        --ports 80
    

    Nachdem Sie die globalen Weiterleitungsregeln erstellt haben, kann es mehrere Minuten dauern, bis die Konfiguration verfügbar ist.

  10. Damit Sie eine Verbindung zu externen Instanzen herstellen können, aktivieren Sie die Firewall im Projekt:

    gcloud compute firewall-rules create www-firewall-80 \
        --target-tags http-server --allow tcp:80
    
    gcloud compute firewall-rules create www-firewall-8888 \
        --target-tags http-server --allow tcp:8888
    
  11. Konvertieren Sie das Bild in ein Format, das an den Server gesendet werden kann:

    cat <<EOF > load_and_convert_image.py
    from PIL import Image
    import numpy as np
    import json
    import codecs
    
    img = Image.open("image.jpg").resize((240, 240))
    img_array=np.array(img)
    result = {
        "instances":[img_array.tolist()]
    }
    file_path="/tmp/out.json"
    print(json.dump(result, codecs.open(file_path, 'w', encoding='utf-8'), separators=(',', ':'), sort_keys=True, indent=4))
    EOF
    
  12. Führen Sie eine Inferenz aus:

    wget https://pixnio.com/free-images/2017/10/31/2017-10-31-10-43-58-1032x825.jpg -O image.jpg
    python load_and_convert_image.py
    curl -X POST $IP/v1/models/default:predict -d @/tmp/out.json
    

    Wenn die Inferenz richtig funktioniert, sieht das Ergebnis in etwa so aus:

    Screenshot: Erfolgreiches Ergebnis einer ausgeführten Inferenz

Bereinigen

Nachdem Sie diese Anleitung abgeschlossen haben, können Sie die in Google Cloud erstellten Ressourcen bereinigen, damit sie keine kostenpflichtigen Kontingente verbrauchen. In den folgenden Abschnitten erfahren Sie, wie Sie diese Ressourcen löschen oder deaktivieren.

  1. Wechseln Sie in der Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite "Ressourcen verwalten"

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen .
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Beenden, um das Projekt zu löschen.

Weitere Informationen