Effettuare il deployment di Falcon-40B con DLC di inferenza di modelli di grandi dimensioni su Amazon SageMaker.

Deploy Falcon-40B with large model inference DLC on Amazon SageMaker.

La settimana scorsa, il Technology Innovation Institute (TII) ha lanciato il TII Falcon LLM, un modello di lingua di base open-source (LLM). Addestrato su 1 trilione di token con Amazon SageMaker, Falcon vanta prestazioni di alto livello (#1 nella classifica di Hugging Face al momento della scrittura) pur essendo relativamente leggero e meno costoso da ospitare rispetto ad altri LLM come llama-65B. In questo post, dimostriamo come distribuire Falcon per applicazioni come la comprensione del linguaggio e l’assistenza alla scrittura automatizzata utilizzando contenitori deep learning per l’elaborazione di grandi modelli su SageMaker.

Il Falcon è atterrato su SageMaker

TII è l’organizzazione di ricerca applicata del Consiglio per la ricerca di tecnologie avanzate di Abu Dhabi; il suo team di scienziati, ricercatori e ingegneri è dedicato alla scoperta di tecnologie trasformative e allo sviluppo di avanzamenti scientifici che renderanno la nostra società resistente al futuro. All’inizio di quest’anno, TII si è proposto di addestrare un LLM open-source all’avanguardia e ha utilizzato l’infrastruttura, gli strumenti e l’esperienza di SageMaker per portare a termine il lavoro (per saperne di più su come questo modello è stato addestrato su SageMaker, fare riferimento a Technology Innovation Institute addestra il modello di base Falcon LLM 40B all’avanguardia su Amazon SageMaker). Il risultato di questo sforzo è il TII Falcon LLM.

Addestrato su 1 trilione di token, Falcon vanta prestazioni di alto livello rispetto all’Eleuther AI Language Model Evaluation Harness ed è attualmente al primo posto nella classifica di Hugging Face per l’accuratezza. Il modello è disponibile in due diverse dimensioni – Falcon-40B e Falcon-7B – e può essere utilizzato per prestazioni all’avanguardia in applicazioni come la comprensione del linguaggio, le esperienze conversazionali e l’assistenza alla scrittura automatizzata. Questo post ti aiuterà a iniziare a distribuire Falcon su SageMaker per inferenze ad alta accuratezza in questi tipi di domini.

I contenitori deep learning per l’elaborazione di grandi modelli semplificano l’hosting di LLM su SageMaker

L’hosting di LLM come Falcon-40B e Falcon-7B può essere impegnativo. I modelli più grandi sono spesso più precisi perché includono miliardi di parametri, ma le loro dimensioni possono anche comportare una latenza di inferenza più lenta o un throughput peggiore. L’hosting di un LLM può richiedere più memoria GPU e kernel ottimizzati per ottenere prestazioni accettabili. Per complicare ulteriormente le cose, anche se i modelli più piccoli come Falcon-7B possono generalmente adattarsi su una singola GPU come un’istanza NVIDIA A10G che alimenta i tipi di istanze AWS G5, i modelli più grandi come Falcon-40B non possono farlo. Quando ciò accade, devono essere utilizzate strategie come il parallelismo tensoriale per suddividere quel modello più grande in più pezzi e sfruttare la memoria di più GPU. Le soluzioni di hosting legacy utilizzate per i modelli più piccoli di solito non offrono questo tipo di funzionalità, aggiungendo alla difficoltà.

I contenitori deep learning per l’elaborazione di grandi modelli di SageMaker (LMI DLC) possono aiutare. I DLC di inferenza di grandi modelli di SageMaker sono una soluzione completa end-to-end per l’hosting di LLM come Falcon-40B. Nella parte anteriore, includono un server di modello ad alte prestazioni (DJL Serving) progettato per l’elaborazione di grandi modelli con funzionalità come lo streaming di token e la replicazione automatica del modello all’interno di un’istanza per aumentare il throughput. Sul retro, i DLC LMI includono anche diversi motori di parallelismo del modello ad alte prestazioni, come DeepSpeed e FasterTransformer, che possono suddividere e gestire i parametri del modello su più GPU. Questi motori includono anche kernel ottimizzati per i modelli di trasformatore popolari, che possono accelerare l’inferenza fino a tre volte più velocemente. Con i DLC LMI, è sufficiente creare un file di configurazione per iniziare l’hosting di LLM su SageMaker. Per saperne di più sui DLC LMI di SageMaker, fare riferimento al parallelismo del modello e all’elaborazione di grandi modelli e alla nostra lista di immagini disponibili. Puoi anche dare un’occhiata al nostro post precedente sull’hosting di Bloom-175B su SageMaker utilizzando i DLC LMI.

Panoramica della soluzione

Questo post ti guiderà attraverso l’hosting di Falcon-40B utilizzando DeepSpeed su SageMaker utilizzando i DLC LMI. Falcon-40B richiede che utilizziamo più GPU A10, mentre Falcon-7B ne richiede solo una. Abbiamo anche preparato degli esempi a cui puoi fare riferimento per l’hosting di Falcon-40B e Falcon-7B utilizzando sia DeepSpeed che Accelerate. Puoi trovare i nostri esempi di codice su GitHub.

Questo esempio può essere eseguito in istanze di notebook SageMaker o in notebook di Amazon SageMaker Studio. Per ospitare Falcon-40B utilizzando LMI e DeepSpeed, dobbiamo utilizzare un’istanza ml.g5.24xlarge. Queste istanze forniscono 4 GPU NVIDIA A10G, ognuna delle quali supporta 96 GiB di memoria GPU. Inoltre, l’host fornisce 96 vCPU e 384 GiB di memoria host. Il contenitore LMI aiuterà ad affrontare gran parte del lavoro pesante non differenziato associato all’hosting di LLM, tra cui il download del modello e la suddivisione dell’artefatto del modello in modo che i suoi parametri costituenti possano essere distribuiti su più GPU.

Le quote per le istanze di machine learning (ML) di SageMaker possono variare tra gli account. Se ricevi un errore che indica di aver superato la quota per le istanze g5.24xlarge mentre segui questo post, puoi aumentare il limite tramite la console di Service Quotas.

Guida alla notebook

Per iniziare, iniziamo installando e importando le dipendenze necessarie per il nostro esempio. Utilizziamo il Boto3 SDK e il SageMaker SDK. Nota che utilizziamo Amazon Simple Storage Service (Amazon S3) per archiviare gli artefatti del modello che abbiamo bisogno per SageMaker e LMI, quindi impostiamo di conseguenza una variabile di prefisso S3. Vedi il seguente codice:

import sagemaker
import jinja2
from sagemaker import image_uris
import boto3
import os
import time
import json
from pathlib import Path
from sagemaker.utils import name_from_base

role = sagemaker.get_execution_role()  # ruolo di esecuzione per l'endpoint
sess = sagemaker.session.Session()  # sessione di SageMaker per interagire con diverse API AWS
bucket = sess.default_bucket()  # bucket per ospitare gli artefatti
model_bucket = sess.default_bucket()  # bucket per ospitare gli artefatti
s3_code_prefix_deepspeed = "hf-large-model-djl-/code_falcon40b/deepspeed"  # cartella all'interno del bucket in cui andrà l'artefatto del codice
region = sess._region_name
account_id = sess.account_id()
s3_client = boto3.client("s3")
sm_client = boto3.client("sagemaker")
smr_client = boto3.client("sagemaker-runtime")
jinja_env = jinja2.Environment()

Ci creiamo quindi una cartella locale per il nostro spazio di lavoro per archiviare gli artefatti del nostro modello:

!mkdir -p code_falcon40b_deepspeed

Creiamo prima un file di configurazione serving.properties nella directory locale che abbiamo creato. Questo file serving.properties indica al contenitore LMI e alla libreria front-end DJL Serving quale motore di parallelizzazione del modello e di ottimizzazione dell’infusione vogliamo utilizzare. Puoi trovare le opzioni di configurazione sia per DeepSpeed che per Hugging Face Accelerate in Configurazioni e impostazioni . Qui, notiamo che impostiamo il parametro option.model_id per definire quale modello Hugging Face scaricare. SageMaker rende semplice lavorare con modelli Hugging Face, e questa singola riga è tutto ciò di cui hai bisogno. Inoltre, impostiamo option.tensor_parallel_degree su un valore di 4 perché abbiamo quattro GPU sulla nostra istanza ml.g5.24xlarge. Questo parametro definisce quante partizioni del modello creare e distribuire. Nota che se avessimo utilizzato un’istanza più grande con otto GPU, come ml.g5.48xlarge, e impostato comunque un valore di 4, allora LMI avrebbe automaticamente creato due repliche del modello (due repliche distribuite su quattro GPU ciascuna). Vedi il seguente codice:

%%writefile ./code_falcon40b_deepspeed/serving.properties
engine=Python
#per distribuire falcon-40b-instruct impostare il valore model_id su 'tiiuae/falcon-40b-instruct'
option.model_id=tiiuae/falcon-40b
option.tensor_parallel_degree=4
#option.s3url = {{s3url}}

Puoi anche sostituire tiiuae/falcon-40b con tiiuae/falcon-40b-instruct se ti soddisfa di più.

Includiamo anche un file requirements.txt che puoi specificare per installare i pacchetti che richiedi:

%%writefile ./code_falcon40b_deepspeed/requirements.txt
einops
torch==2.0.1

L’ultima cosa di cui abbiamo bisogno è il file model.py che verrà utilizzato con il tuo modello:

%%writefile ./code_falcon40b_deepspeed/model.py
from djl_python import Input, Output
import os
import torch
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
from typing import Any, Dict, Tuple
import warnings

predictor = None


def get_model(properties):
    model_name = properties["model_id"]
    local_rank = int(os.getenv("LOCAL_RANK", "0"))
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        low_cpu_mem_usage=True,
        trust_remote_code=True,
        torch_dtype=torch.bfloat16,
        device_map="auto",
    )
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    generator = pipeline(
        task="text-generation", model=model, tokenizer=tokenizer, device_map="auto"
    )
    return generator


def handle(inputs: Input) -> None:
    global predictor
    if not predictor:
        predictor = get_model(inputs.get_properties())
    if inputs.is_empty():
        # Il server del modello effettua una chiamata vuota per riscaldare il modello all'avvio
        return None
    data = inputs.get_as_json()
    text = data["text"]
    text_length = data["text_length"]
    outputs = predictor(text, do_sample=True, min_length=text_length, max_length=text_length)
    result = {"outputs": outputs}
    return Output().add_as_json(result)

Ecco fatto! A questo punto abbiamo creato tutti gli artefatti di cui avrai bisogno per distribuire Falcon-40B con DeepSpeed! Incapsuliamo la directory in un file *.tar.gz e lo carichiamo su Amazon S3. Si noti che il modello effettivo non è stato scaricato o incluso in questo file. Il container LMI scaricherà il modello per te direttamente da Hugging Face. In alternativa, hai la possibilità di puntare a un bucket S3 se desideri la tua copia del modello in una posizione più performante per il download. LMI include anche l’ottimizzazione per il download da Amazon S3 ad alta performance. Vedere il seguente codice:

s3_code_artifact_deepspeed = sess.upload_data("model.tar.gz", bucket, s3_code_prefix_deepspeed)
print(f"Artefatto per codice S3 o modello tar per deepspeed caricato su --- > {s3_code_artifact_deepspeed}")

A questo punto, tutto ciò che resta da fare è definire il container che vogliamo utilizzare e creare un oggetto modello:

inference_image_uri = (
    f"763104351884.dkr.ecr.{region}.amazonaws.com/djl-inference:0.22.1-deepspeed0.8.3-cu118"
)
model_name_acc = name_from_base(f"falcon40b-model-ds")
create_model_response = sm_client.create_model(
    ModelName=model_name_acc,
    ExecutionRoleArn=role,
    PrimaryContainer={"Image": inference_image_uri, "ModelDataUrl": s3_code_artifact_deepspeed},
)
model_arn = create_model_response["ModelArn"]

Quindi creiamo una configurazione del punto di arrivo e creiamo il punto di arrivo:

endpoint_config_name = f"{model_name}-config"
endpoint_name = f"{model_name}-endpoint"
endpoint_config_response = sm_client.create_endpoint_config(
    EndpointConfigName=endpoint_config_name,
    ProductionVariants=[
        {
            "VariantName": "variant1",
            "ModelName": model_name,
            "InstanceType": "ml.g5.24xlarge",
            "InitialInstanceCount": 1,
            "ModelDataDownloadTimeoutInSeconds": 3600,
            "ContainerStartupHealthCheckTimeoutInSeconds": 3600,
            # "VolumeSizeInGB": 512
        },
    ],
)
endpoint_config_response

create_endpoint_response = sm_client.create_endpoint(
    EndpointName=f"{endpoint_name}", EndpointConfigName=endpoint_config_name
)
print(f"Punto di arrivo creato: {create_endpoint_response['EndpointArn']}")

Elementi di configurazione da tenere a mente per un hosting di successo

Una considerazione importante per l’hosting di modelli di grandi dimensioni è assicurarsi che ci sia il tempo sufficiente per il download del modello da Hugging Face. Nei nostri test, il Falcon-40B ha impiegato circa 90 minuti per il download sull’istanza. Un insieme chiave di configurazioni per consentire ciò sono ContainerStartupHealthCheckTimeoutInSeconds e ModelDataDownloadTimeoutInSeconds. Assicurati che la configurazione del punto di arrivo di SageMaker abbia un valore di 3600 per ognuno di questi. Inoltre, è molto più facile scaricare da Amazon S3 invece dello zoo originale dei modelli utilizzando i container LMI appositamente progettati per LLMS che utilizzano l’utilità S5cmd, che riduce il tempo di download del modello a circa 10 minuti.

Puoi monitorare lo stato del punto di arrivo chiamando DescribeEndpoint, che ti dirà quando tutto è completo. Il tuo punto di arrivo è ora pronto a rispondere alle richieste di inferenza! Poiché LMI gestisce la partizione e l’orchestrazione del modello per te, ogni richiesta verrà elaborata utilizzando tutti e 4 i GPU disponibili sulla nostra istanza ml.g5.12xlarge. Ciò ci consente di ospitare LLMs e aumentare le prestazioni se si scalano gli acceleratori GPU in orizzontale. Vedere il seguente codice:

response_model = smr_client.invoke_endpoint(
    EndpointName=endpoint_name,
    Body=json.dumps({"text": "Qual è lo scopo della vita?", "text_length": 150}),
    ContentType="application/json",
)

response_model["Body"].read().decode("utf8")

Se hai finito e desideri eliminare la configurazione del punto di arrivo, il punto di arrivo e l’oggetto modello, puoi eseguire i seguenti comandi:

sm_client.delete_endpoint(EndpointName=endpoint_name)
sm_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name)
sm_client.delete_model(ModelName=model_name)

Questo codice a cui abbiamo fatto riferimento in questo post può essere trovato nel notebook completo su GitHub.

Conclusione

SageMaker Hosting e LMI DLC rendono facile l’hosting di LLMs come Falcon-40B. Si occupa della parte pesante non differenziata nell’orchestrazione di ciò che è richiesto per ospitare modelli su più GPU e fornisce opzioni configurabili per soddisfare le tue esigenze. Inoltre, l’uso dei modelli Hugging Face diventa molto semplice, con il supporto integrato per questi modelli.

In questo post abbiamo mostrato come utilizzare SageMaker per ospitare il modello Falcon-40B utilizzando DeepSpeed. Inoltre, abbiamo fornito degli esempi su GitHub per ospitare Falcon-40B utilizzando Accelerate e i modelli più piccoli Falcon-7B. Ti incoraggiamo a provare questa esperienza su SageMaker con LMI e ad approfondire le tue conoscenze sul miglior modello LLM disponibile pubblicamente ad oggi!