Maksimer stabil diffusionsydelse og sænk slutningsomkostninger med AWS Inferentia2 | Amazon Web Services

Maksimer stabil diffusionsydelse og sænk slutningsomkostninger med AWS Inferentia2 | Amazon Web Services

Generative AI-modeller har oplevet hurtig vækst i de seneste måneder på grund af deres imponerende evner til at skabe realistisk tekst, billeder, kode og lyd. Blandt disse modeller skiller stabile diffusionsmodeller sig ud for deres unikke styrke ved at skabe billeder af høj kvalitet baseret på tekstprompter. Stabil diffusion kan generere en bred vifte af billeder i høj kvalitet, herunder realistiske portrætter, landskaber og endda abstrakt kunst. Og ligesom andre generative AI-modeller kræver stabile diffusionsmodeller kraftig databehandling for at give inferens med lav latens.

I dette indlæg viser vi, hvordan du kan køre stabile diffusionsmodeller og opnå høj ydeevne til den laveste pris i Amazon Elastic Compute Cloud (Amazon EC2) ved hjælp af Amazon EC2 Inf2-forekomster drives af AWS Inferentia2. Vi ser på arkitekturen af ​​en stabil diffusionsmodel og gennemgår trinene til at kompilere en stabil diffusionsmodel vha. AWS Neuron og implementere det til en Inf2-instans. Vi diskuterer også de optimeringer, som Neuron SDK automatisk foretager for at forbedre ydeevnen. Du kan køre både Stable Diffusion 2.1 og 1.5 versioner på AWS Inferentia2 omkostningseffektivt. Til sidst viser vi, hvordan du kan implementere en stabil diffusionsmodel til en Inf2-instans med Amazon SageMaker.

Stable Diffusion 2.1-modelstørrelsen i flydende komma 32 (FP32) er 5 GB og 2.5 GB i bfoat16 (BF16). En enkelt inf2.xlarge-instans har én AWS Inferentia2-accelerator med 32 GB HBM-hukommelse. Stable Diffusion 2.1-modellen kan passe på en enkelt inf2.xlarge-instans. Stable Diffusion er en tekst-til-billede-model, som du kan bruge til at skabe billeder af forskellige stilarter og indhold blot ved at give en tekstprompt som input. For at lære mere om den stabile diffusionsmodelarkitektur, se Skab billeder i høj kvalitet med stabile diffusionsmodeller, og implementer dem omkostningseffektivt med Amazon SageMaker.

Hvordan Neuron SDK optimerer stabil diffusionsydelse

Før vi kan implementere Stable Diffusion 2.1-modellen på AWS Inferentia2-instanser, skal vi kompilere modelkomponenterne ved hjælp af Neuron SDK. Neuron SDK, som inkluderer en deep learning-kompiler, runtime og værktøjer, kompilerer og optimerer automatisk deep learning-modeller, så de kan køre effektivt på Inf2-instanser og udtrække fuld ydeevne af AWS Inferentia2-acceleratoren. Vi har eksempler til rådighed for Stable Diffusion 2.1-modellen på GitHub repo. Denne notesbog præsenterer et ende-til-ende eksempel på, hvordan man kompilerer en stabil diffusionsmodel, gemmer de kompilerede Neuron-modeller og indlæser den i kørselstiden til slutning.

Vi anvender StableDiffusionPipeline fra det kramme ansigt diffusers bibliotek for at indlæse og kompilere modellen. Vi kompilerer derefter alle komponenterne i modellen til Neuron vha torch_neuronx.trace() og gem den optimerede model som TorchScript. Kompileringsprocesser kan være ret hukommelsesintensive og kræver en betydelig mængde RAM. For at omgå dette, før vi sporer hver model, opretter vi en deepcopy af den del af rørledningen, der spores. Efter dette sletter vi pipeline-objektet fra hukommelsen vha del pipe. Denne teknik er især nyttig, når du kompilerer på instanser med lav RAM.

Derudover udfører vi også optimeringer til de stabile diffusionsmodeller. UNet har det mest beregningsintensive aspekt af slutningen. UNet-komponenten fungerer på inputtensorer, der har en batchstørrelse på to, og genererer en tilsvarende outputtensor også med en batchstørrelse på to, for at producere et enkelt billede. Elementerne i disse partier er fuldstændig uafhængige af hinanden. Vi kan drage fordel af denne adfærd til at få optimal latenstid ved at køre en batch på hver Neuron-kerne. Vi kompilerer UNet for én batch (ved at bruge inputtensorer med én batch), og bruger derefter torch_neuronx.DataParallel API til at indlæse denne enkelt batch-model på hver kerne. Outputtet af denne API er et sømløst to-batch-modul: vi kan overføre input fra to batches til UNet, og et to-batch-output returneres, men internt kører de to single-batch-modeller på de to Neuron-kerner . Denne strategi optimerer ressourceudnyttelsen og reducerer latens.

Kompiler og implementer en stabil diffusionsmodel på en Inf2 EC2-instans

For at kompilere og implementere den stabile diffusionsmodel på en Inf2 EC2-instans skal du logge på AWS Management Console og opret en inf2.8xlarge instans. Bemærk, at en inf2.8xlarge-instans kun kræves til kompilering af modellen, fordi kompilering kræver en højere værtshukommelse. Stable Diffusion-modellen kan hostes på en inf2.xlarge-instans. Du kan finde den seneste AMI med Neuron-biblioteker ved at bruge følgende AWS kommandolinjegrænseflade (AWS CLI) kommando:

aws ec2 describe-images --region us-east-1 --owners amazon --filters 'Name=name,Values=Deep Learning AMI Neuron PyTorch 1.13.? (Amazon Linux 2) ????????' 'Name=state,Values=available' --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' --output text

Til dette eksempel oprettede vi en EC2-instans ved hjælp af Deep Learning AMI Neuron PyTorch 1.13 (Ubuntu 20.04). Du kan derefter oprette et JupyterLab-labmiljø ved at oprette forbindelse til instansen og køre følgende trin:

run source /opt/aws_neuron_venv_pytorch/bin/activate
pip install jupyterlab
jupyter-lab

En notesbog med alle trin til kompilering og hosting af modellen er placeret på GitHub.

Lad os se på kompileringstrinene for en af ​​tekstkoderblokkene. Andre blokke, der er en del af den stabile diffusionspipeline, kan kompileres på samme måde.

Det første skridt er at indlæse den fortrænede model fra Hugging Face. Det StableDiffusionPipeline.from_pretrained metode indlæser den fortrænede model i vores pipeline-objekt, pipe. Så laver vi en deepcopy af tekstkoderen fra vores pipeline, hvilket effektivt kloner den. Det del pipe kommandoen bruges derefter til at slette det originale pipeline-objekt, hvilket frigør den hukommelse, der blev brugt af det. Her kvantiserer vi modellen til BF16-vægte:

model_id = "stabilityai/stable-diffusion-2-1-base"
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16)
text_encoder = copy.deepcopy(pipe.text_encoder)
del pipe

Dette trin involverer indpakning af vores tekstkoder med NeuronTextEncoder indpakning. Outputtet fra et kompileret tekstkodermodul vil være af dict. Vi konverterer det til en list skriv ved hjælp af denne indpakning:

text_encoder = NeuronTextEncoder(text_encoder)

Vi initialiserer PyTorch tensor emb med nogle værdier. Det emb tensor bruges som eksempel input til torch_neuronx.trace fungere. Denne funktion sporer vores tekstkoder og kompilerer den til et format, der er optimeret til Neuron. Biblioteksstien til den kompilerede model er konstrueret ved joining COMPILER_WORKDIR_ROOT med underbiblioteket text_encoder:

emb = torch.tensor([...])
text_encoder_neuron = torch_neuronx.trace(
        text_encoder.neuron_text_encoder,
        emb,
        compiler_workdir=os.path.join(COMPILER_WORKDIR_ROOT, 'text_encoder'),
        )

Den kompilerede tekstkoder gemmes vha torch.jit.save. Det er gemt under filnavnet model.pt i text_encoder bibliotek af vores compilers arbejdsområde:

text_encoder_filename = os.path.join(COMPILER_WORKDIR_ROOT, 'text_encoder/model.pt')
torch.jit.save(text_encoder_neuron, text_encoder_filename)

notesbog indeholder lignende trin til kompilering af andre komponenter i modellen: UNet, VAE-dekoder og VAE post_quant_conv. Når du har kompileret alle modellerne, kan du indlæse og køre modellen ved at følge disse trin:

  1. Definer stierne til de kompilerede modeller.
  2. Indlæs en foruddannet StableDiffusionPipeline model, med dens konfiguration specificeret til at bruge bfloat16 datatypen.
  3. Indlæs UNet-modellen på to Neuron-kerner ved hjælp af torch_neuronx.DataParallel API. Dette gør det muligt at udføre data parallel inferens, hvilket kan fremskynde modellens ydeevne betydeligt.
  4. Indlæs de resterende dele af modellen (text_encoder, decoderog post_quant_conv) på en enkelt neuronkerne.

Du kan derefter køre pipelinen ved at angive inputtekst som prompter. Følgende er nogle billeder genereret af modellen til meddelelserne:

  • Portræt af renaud sechan, pen og blæk, indviklede stregtegninger, af craig mullins, ruan jia, kentaro miura, greg rutkowski, loundraw

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • Portræt af gammel kulminearbejder i det 19. århundrede, smukt maleri, med meget detaljeret ansigtsmaling af greg rutkowski

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • Et slot midt i en skov

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Host Stable Diffusion 2.1 på AWS Inferentia2 og SageMaker

Hosting af stabile diffusionsmodeller med SageMaker kræver også kompilering med Neuron SDK. Du kan fuldføre kompileringen i forvejen eller under kørsel ved hjælp af LMI-beholdere (Large Model Inference). Kompilering på forhånd giver mulighed for hurtigere modelindlæsningstider og er den foretrukne mulighed.

SageMaker LMI-containere giver to måder at implementere modellen på:

  • En kodefri mulighed, hvor vi blot leverer en serving.properties fil med de nødvendige konfigurationer
  • Medbring dit eget slutningsskrift

Vi ser på begge løsninger og gennemgår konfigurationerne og inferensscriptet (model.py). I dette indlæg demonstrerer vi implementeringen ved hjælp af en præ-kompileret model gemt i en Amazon Simple Storage Service (Amazon S3) spand. Du kan bruge denne prækompilerede model til dine implementeringer.

Konfigurer modellen med et medfølgende script

I dette afsnit viser vi, hvordan man konfigurerer LMI-beholderen til at være vært for de stabile diffusionsmodeller. SD2.1 notebook tilgængelig på GitHub. Det første trin er at oprette modelkonfigurationspakken i henhold til følgende mappestruktur. Vores mål er at bruge de minimale modelkonfigurationer, der er nødvendige for at være vært for modellen. Den nødvendige mappestruktur er som følger:

<config-root-directory> / 
    ├── serving.properties
    │   
    └── model.py [OPTIONAL]

Dernæst opretter vi serveringsejendomme fil med følgende parametre:

%%writefile code_sd/serving.properties
engine=Python
option.entryPoint=djl_python.transformers-neuronx
option.use_stable_diffusion=True
option.model_id=s3url
option.tensor_parallel_degree=2
option.dtype=bf16

Parametrene angiver følgende:

  • option.model_id – LMI-beholderne bruger s5cmd til at indlæse modellen fra S3-lokationen, og derfor er vi nødt til at angive placeringen af, hvor vores kompilerede vægte er.
  • option.entryPoint – For at bruge de indbyggede handlere specificerer vi transformers-neuronx-klassen. Hvis du har et brugerdefineret inferensscript, skal du angive det i stedet.
  • option.dtype – Dette specificerer at indlæse vægtene i en bestemt størrelse. Til dette indlæg bruger vi BF16, som yderligere reducerer vores hukommelseskrav i forhold til FP32 og sænker vores latenstid på grund af det.
  • option.tensor_parallel_degree – Denne parameter angiver antallet af acceleratorer, vi bruger til denne model. AWS Inferentia2-chipacceleratoren har to Neuron-kerner, og hvis du angiver en værdi på 2, betyder det, at vi bruger en accelerator (to kerner). Det betyder, at vi nu kan oprette flere arbejdere for at øge gennemløbet af slutpunktet.
  • option.motor – Dette er indstillet til Python for at indikere, at vi ikke vil bruge andre compilere som DeepSpeed ​​eller Faster Transformer til denne hosting.

Medbring dit eget manuskript

Hvis du vil medbringe dit eget brugerdefinerede inferensscript, skal du fjerne option.entryPoint fra serving.properties. LMI-beholderen vil i så fald lede efter en model.py fil samme sted som serving.properties og bruge det til at køre konklusionen.

Opret dit eget slutningsscript (model.py)

At oprette dit eget inferensscript er relativt ligetil ved at bruge LMI-beholderen. Beholderen kræver din model.py fil for at have en implementering af følgende metode:

def handle(inputs: Input) which returns an object of type Outputs

Lad os undersøge nogle af de kritiske områder af vedhæftede notesbog, som demonstrerer funktionen medbring dit eget script.

Udskift cross_attention modul med den optimerede version:

# Replace original cross-attention module with custom cross-attention module for better performance
    CrossAttention.get_attention_scores = get_attention_scores
Load the compiled weights for the following
text_encoder_filename = os.path.join(COMPILER_WORKDIR_ROOT, 'text_encoder.pt')
decoder_filename = os.path.join(COMPILER_WORKDIR_ROOT, 'vae_decoder.pt')
unet_filename = os.path.join(COMPILER_WORKDIR_ROOT, 'unet.pt')
post_quant_conv_filename =. os.path.join(COMPILER_WORKDIR_ROOT, 'vae_post_quant_conv.pt')

Dette er navnene på den kompilerede vægtfil, vi brugte, da vi lavede kompileringerne. Du er velkommen til at ændre filnavnene, men sørg for, at dine vægte-filnavne stemmer overens med det, du angiver her.

Så skal vi indlæse dem ved hjælp af Neuron SDK og indstille disse i de faktiske modelvægte. Når du indlæser de UNet-optimerede vægte, skal du bemærke, at vi også angiver antallet af neuronkerner, vi skal indlæse disse på. Her indlæser vi til en enkelt accelerator med to kerner:

# Load the compiled UNet onto two neuron cores.
    pipe.unet = NeuronUNet(UNetWrap(pipe.unet))
    logging.info(f"Loading model: unet:created")
    device_ids = [idx for idx in range(tensor_parallel_degree)]
   
    pipe.unet.unetwrap = torch_neuronx.DataParallel(torch.jit.load(unet_filename), device_ids, set_dynamic_batching=False)
   
 
    # Load other compiled models onto a single neuron core.
 
    # - load encoders
    pipe.text_encoder = NeuronTextEncoder(pipe.text_encoder)
    clip_compiled = torch.jit.load(text_encoder_filename)
    pipe.text_encoder.neuron_text_encoder = clip_compiled
    #- load decoders
    pipe.vae.decoder = torch.jit.load(decoder_filename)
    pipe.vae.post_quant_conv = torch.jit.load(post_quant_conv_filename)

Kørsel af slutningen med en prompt påkalder rørobjektet for at generere et billede.

Opret SageMaker-slutpunktet

Vi bruger Boto3 API'er til at skabe et SageMaker-slutpunkt. Udfør følgende trin:

  1. Lav tarballen med kun serveringen og det valgfrie model.py filer og upload det til Amazon S3.
  2. Opret modellen ved hjælp af billedbeholderen og modeltarballen, der blev uploadet tidligere.
  3. Opret slutpunktskonfigurationen ved hjælp af følgende nøgleparametre:
    1. Brug en ml.inf2.xlarge instans.
    2. sæt ContainerStartupHealthCheckTimeoutInSeconds til 240 for at sikre, at sundhedstjekket starter, efter at modellen er implementeret.
    3. sæt VolumeInGB til en større værdi, så den kan bruges til at indlæse modelvægte, der er 32 GB i størrelse.

Opret en SageMaker-model

Når du har oprettet model.tar.gz-filen og uploadet den til Amazon S3, skal vi oprette en SageMaker-model. Vi bruger LMI-beholderen og modelartefakten fra det forrige trin til at skabe SageMaker-modellen. SageMaker giver os mulighed for at tilpasse og injicere forskellige miljøvariabler. For denne arbejdsgang kan vi lade alt være som standard. Se følgende kode:

inference_image_uri = (
    f"763104351884.dkr.ecr.{region}.amazonaws.com/djl-inference:0 djl-serving-inf2"
)

Opret modelobjektet, som i det væsentlige opretter en lockdown-beholder, der indlæses på instansen og bruges til at konkludere:

model_name = name_from_base(f"inf2-sd")
create_model_response = boto3_sm_client.create_model(
    ModelName=model_name,
    ExecutionRoleArn=role,
    PrimaryContainer={"Image": inference_image_uri, "ModelDataUrl": s3_code_artifact},
)

Opret et SageMaker-slutpunkt

I denne demo bruger vi en ml.inf2.xlarge-instans. Vi skal indstille VolumeSizeInGB parametre for at give den nødvendige diskplads til at indlæse modellen og vægtene. Denne parameter gælder for instanser, der understøtter Amazon Elastic Block Store (Amazon EBS) volumentilslutning. Vi kan lade modeldownload-timeout og containerstart-sundhedstjekket blive til en højere værdi, hvilket vil give containeren tilstrækkelig tid til at trække vægtene fra Amazon S3 og indlæse i AWS Inferentia2-acceleratorerne. For flere detaljer, se CreateEndpointConfig.

endpoint_config_response = boto3_sm_client.create_endpoint_config( EndpointConfigName=endpoint_config_name,
    ProductionVariants=[
        {
            "VariantName": "variant1",
            "ModelName": model_name,
            "InstanceType": "ml.inf2.xlarge", # - 
            "InitialInstanceCount": 1,
            "ContainerStartupHealthCheckTimeoutInSeconds": 360, 
            "VolumeSizeInGB": 400
        },
    ],
)

Til sidst opretter vi et SageMaker-slutpunkt:

create_endpoint_response = boto3_sm_client.create_endpoint(
    EndpointName=f"{endpoint_name}", EndpointConfigName=endpoint_config_name
)

Kald modellens slutpunkt

Dette er en generativ model, så vi sender den prompt, som modellen bruger til at generere billedet. Nyttelasten er af typen JSON:

response_model = boto3_sm_run_client.invoke_endpoint( EndpointName=endpoint_name,
    Body=json.dumps(
        {
            "prompt": "Mountain Landscape", 
            "parameters": {} # 
        }
    ), 
    ContentType="application/json",
)

Benchmarking af den stabile diffusionsmodel på Inf2

Vi kørte et par test for at benchmarke den stabile diffusionsmodel med BF 16-datatypen på Inf2, og vi er i stand til at udlede latency-tal, der konkurrerer med eller overgår nogle af de andre acceleratorer for stabil diffusion. Dette, kombineret med de lavere omkostninger ved AWS Inferentia2-chips, gør dette til et ekstremt værdifuldt forslag.

Følgende tal er fra den stabile diffusionsmodel, der er implementeret på en inf2.xl-instans. For mere information om omkostninger, se Amazon EC2 Inf2-forekomster.

Model Løsning Datatype gentagelser P95 latens (ms) Inf2.xl On-Demand pris pr. time Inf2.xl (pris pr. billede)
Stabil diffusion 1.5 512 × 512 bf16 50 2,427.4 $0.76 $0.0005125
Stabil diffusion 1.5 768 × 768 bf16 50 8,235.9 $0.76 $0.0017387
Stabil diffusion 1.5 512 × 512 bf16 30 1,456.5 $0.76 $0.0003075
Stabil diffusion 1.5 768 × 768 bf16 30 4,941.6 $0.76 $0.0010432
Stabil diffusion 2.1 512 × 512 bf16 50 1,976.9 $0.76 $0.0004174
Stabil diffusion 2.1 768 × 768 bf16 50 6,836.3 $0.76 $0.0014432
Stabil diffusion 2.1 512 × 512 bf16 30 1,186.2 $0.76 $0.0002504
Stabil diffusion 2.1 768 × 768 bf16 30 4,101.8 $0.76 $0.0008659

Konklusion

I dette indlæg dykkede vi dybt ned i kompileringen, optimeringen og implementeringen af ​​den stabile diffusion 2.1-modellen ved hjælp af Inf2-instanser. Vi demonstrerede også implementering af stabile diffusionsmodeller ved hjælp af SageMaker. Inf2-forekomster leverer også fantastisk prisydelse til Stable Diffusion 1.5. For at lære mere om, hvorfor Inf2-instanser er gode til generativ AI og store sprogmodeller, se Amazon EC2 Inf2-instanser til lavpris, højtydende generativ AI-inferens er nu generelt tilgængelige. For detaljer om ydeevne, se Inf2 ydeevne. Se yderligere eksempler på GitHub repo.

Særlig tak til Matthew Mcclain, Beni Hegedus, Kamran Khan, Shruti Koparkar og Qing Lan for at gennemgå og levere værdifulde input.


Om forfatterne

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Vivek Gangasani er Senior Machine Learning Solutions Architect hos Amazon Web Services. Han arbejder med maskinlæringsstartups for at bygge og implementere AI/ML-applikationer på AWS. Han er i øjeblikket fokuseret på at levere løsninger til MLOps, ML-inferens og lavkode-ML. Han har arbejdet på projekter inden for forskellige domæner, herunder naturlig sprogbehandling og computersyn.

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.KC Tung er senior løsningsarkitekt i AWS Annapurna Labs. Han har specialiseret sig i store dybe læringsmodeller og implementering i stor skala i skyen. Han har en ph.d. i molekylær biofysik fra University of Texas Southwestern Medical Center i Dallas. Han har talt ved AWS Summits og AWS Reinvent. I dag hjælper han kunder med at træne og implementere store PyTorch- og TensorFlow-modeller i AWS-skyen. Han er forfatter til to bøger: Lær TensorFlow Enterprise , TensorFlow 2 Pocket Reference.

Maximize Stable Diffusion performance and lower inference costs with AWS Inferentia2 | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.Rupinder Grewal er en Sr Ai/ML Specialist Solutions Architect hos AWS. Han fokuserer i øjeblikket på servering af modeller og MLOps på SageMaker. Før denne rolle har han arbejdet som Machine Learning Engineer ved at bygge og hoste modeller. Uden for arbejdet nyder han at spille tennis og cykle på bjergstier.

Tidsstempel:

Mere fra AWS maskinindlæring