Gestione del modello per modelli LoRA ottimizzati utilizzando Llama2 e Amazon SageMaker

Gestione ottimizzata del modello per modelli LoRA utilizzando Llama2 e Amazon SageMaker

Nell’era dei big data e dell’AI, le aziende sono continuamente alla ricerca di modi per utilizzare queste tecnologie per ottenere un vantaggio competitivo. Una delle aree più calde dell’IA al momento è l’IA generativa, e per buoni motivi. L’IA generativa offre soluzioni potenti che spingono i confini di ciò che è possibile in termini di creatività e innovazione. Al centro di queste soluzioni all’avanguardia si trova un modello di base (FM), un modello di apprendimento automatico altamente avanzato pre-addestrato su enormi quantità di dati. Molti di questi modelli di base hanno dimostrato una notevole capacità di comprendere e generare testi simili a quelli umani, rendendoli uno strumento prezioso per una varietà di applicazioni, dalla creazione di contenuti all’automazione del supporto clienti.

Tuttavia, questi modelli non sono privi di sfide. Sono eccezionalmente grandi e richiedono grandi quantità di dati e risorse computazionali per l’addestramento. Inoltre, ottimizzare il processo di addestramento e calibrare i parametri può essere un processo complesso e iterativo, che richiede competenze e attenta sperimentazione. Questi possono essere ostacoli per molte organizzazioni che cercano di costruire i propri modelli di base. Per superare questa sfida, molti clienti stanno considerando di raffinare i modelli di base esistenti. Questa è una tecnica popolare per regolare una piccola parte dei parametri del modello per applicazioni specifiche, preservando allo stesso tempo le conoscenze già codificate nel modello. Consente alle organizzazioni di utilizzare la potenza di questi modelli riducendo le risorse necessarie per personalizzarli per un dominio o un compito specifico.

Ci sono due approcci principali per il raffinamento dei modelli di base: il raffinamento tradizionale e il raffinamento efficiente dei parametri. Il raffinamento tradizionale prevede l’aggiornamento di tutti i parametri del modello pre-addestrato per un compito specifico. D’altra parte, il raffinamento efficiente dei parametri include una varietà di tecniche che permettono la personalizzazione di un modello senza aggiornare tutti i parametri originali del modello. Una di queste tecniche si chiama Low-rank Adaptation (LoRA). Questa tecnica prevede l’aggiunta di moduli piccoli e specifici del compito al modello pre-addestrato e l’addestramento di essi, mantenendo gli altri parametri fissi come mostrato nell’immagine seguente.

Fonte: Generative AI on AWS (O’Reilly, 2023)

LoRA ha guadagnato popolarità recentemente per diversi motivi. Offre un addestramento più veloce, requisiti di memoria ridotti e la possibilità di riutilizzare modelli pre-addestrati per molteplici compiti. Ancora più importante, il modello di base e l’adattatore possono essere archiviati separatamente e combinati in qualsiasi momento, rendendo più facile conservare, distribuire e condividere versioni raffinate. Tuttavia, questo introduce una nuova sfida: come gestire correttamente questi nuovi tipi di modelli raffinati. Dovresti combinare il modello di base e l’adattatore o mantenerli separati? In questo post, esamineremo le migliori pratiche per la gestione dei modelli raffinati con LoRA su Amazon SageMaker per affrontare questa domanda emergente.

Lavorare con FM su SageMaker Model Registry

In questo post, esamineremo un esempio completo di raffinamento del grande modello di linguaggio Llama2 (LLM) utilizzando il metodo QLoRA. QLoRA combina i vantaggi del raffinamento efficiente dei parametri con la quantizzazione a 4 bit/8 bit per ridurre ulteriormente le risorse richieste per raffinare un FM per un compito o un caso d’uso specifico. A tal fine, utilizzeremo il modello pre-addestrato Llama2 con 7 miliardi di parametri e lo raffineremo sul dataset databricks-dolly-15k. I LLM, come Llama2, hanno miliardi di parametri e vengono pre-addestrati su enormi dataset di testo. Il raffinamento adatta un LLM a un compito successivo utilizzando un dataset più piccolo. Tuttavia, il raffinamento di modelli grandi è computazionalmente costoso. Ecco perché utilizzeremo il metodo QLoRA per quantizzare i pesi durante il raffinamento per ridurre questo costo computazionale.

Negli esempi troverai due notebook (llm-finetune-combined-with-registry.ipynb e llm-finetune-separate-with-registry.ipynb). Ognuno illustra un modo diverso per gestire i modelli raffinati con LoRA come illustrato nel diagramma seguente:

  1. Prima di tutto, scarichiamo il modello pre-allenato Llama2 con 7 miliardi di parametri utilizzando i Quaderni di SageMaker Studio. I modelli LLM, come Llama2, hanno dimostrato prestazioni all’avanguardia nelle attività di elaborazione del linguaggio naturale (NLP) quando vengono sintonizzati sulle specifiche del dominio.
  2. Successivamente, sintonizziamo Llama2 sul dataset databricks-dolly-15k utilizzando il metodo QLoRA. QLoRA riduce il costo computazionale della sintonizzazione sottoponendo a quantizzazione i pesi del modello.
  3. Durante la sintonizzazione, integriamo SageMaker Experiments Plus con l’API Transformers per registrare automaticamente metriche come il gradiente, la perdita, ecc.
  4. Successivamente, versioniamo il modello Llama2 sintonizzato nel Registro modelli di SageMaker utilizzando due approcci:
    1. Archiviando l’intero modello
    2. Archiviando l’adattatore e il modello base separatamente.
  5. Infine, ospitiamo i modelli Llama2 sintonizzati utilizzando Deep Java Library (DJL) Serving su un endpoint in tempo reale di SageMaker.

Nelle sezioni successive, approfondiremo ciascuno di questi passaggi per mostrare la flessibilità di SageMaker per diversi flussi di lavoro LLM e come queste funzionalità possano contribuire a migliorare le operazioni dei tuoi modelli.

Prerequisiti

Completare i seguenti prerequisiti per iniziare a sperimentare con il codice.

  • Creare un Dominio SageMaker Studio: Amazon SageMaker Studio, in particolare i Quaderni di studio, viene utilizzato per avviare il compito di sintonizzazione fine di Llama2, quindi registrare e visualizzare modelli all’interno del Registro modelli di SageMaker. SageMaker Experiments viene utilizzato anche per visualizzare e confrontare i log dei compiti di sintonizzazione fine di Llama2 (perdita di allenamento/perdita di test, ecc.).
  • Creare un bucket di Amazon Simple Storage Service (S3): È necessario avere accesso a un bucket S3 per archiviare artefatti di formazione e pesi del modello. Per istruzioni, fare riferimento alla guida Creazione di un bucket. Il codice di esempio utilizzato per questo post utilizzerà il bucket S3 predefinito di SageMaker, ma è possibile personalizzarlo per utilizzare qualsiasi bucket S3 pertinente.
  • Configurare Raccolte modelli (autorizzazioni IAM): Aggiornare il ruolo di esecuzione di SageMaker con le autorizzazioni per le risorse dei gruppi di risorse elencate nella Guida per sviluppatori delle Raccolte modelli del Registro modelli per implementare la suddivisione del Registro modelli utilizzando Raccolte modelli.
  • Accettare i Termini e condizioni per Llama2: È necessario accettare il contratto di licenza per utente finale e la politica di utilizzo accettabile per utilizzare il modello di base Llama2.

Gli esempi sono disponibili nel repository GitHub. I file del notebook sono testati utilizzando i notebook di Studio basati su kernel PyTorch 2.0.0 Python 3.10 GPU Ottimizzato e tipo di istanza ml.g4dn.xlarge.

Integrazione callback di Experiments Plus

Amazon SageMaker Experiments ti consente di organizzare, tenere traccia, confrontare e valutare esperimenti di apprendimento automatico (ML) e versioni del modello da qualsiasi ambiente di sviluppo integrato (IDE), incluso Jupyter Notebooks locale, utilizzando l’SDK Python di SageMaker o boto3. Fornisce la flessibilità di registrare le metriche del tuo modello, i parametri, i file, gli artefatti, tracciare grafici dalle diverse metriche, catturare metadati vari, cercarli e supportare la riproducibilità del modello. Gli scienziati dei dati possono confrontare rapidamente le prestazioni e gli iperparametri per la valutazione del modello attraverso grafici e tabelle visive. Possono anche utilizzare SageMaker Experiments per scaricare i grafici creati e condividere la valutazione del modello con gli stakeholder.

L’addestramento dei LLM può essere un processo lento, costoso e iterativo. È molto importante per un utente tenere traccia dell’esperimentazione dei LLM su larga scala per evitare un’esperienza di messa a punto del modello inconsistente. Le API di HuggingFace Transformers consentono agli utenti di tracciare le metriche durante le attività di addestramento tramite Callbacks. Le Callbacks sono frammenti di codice “sola lettura” che possono personalizzare il comportamento del ciclo di addestramento nel Trainer di PyTorch, che possono ispezionare lo stato del ciclo di addestramento per la segnalazione del progresso, il registro su TensorBoard o SageMaker Experiments Plus tramite logica personalizzata (che è inclusa come parte di questa base di codice).

È possibile importare il codice di callback di SageMaker Experiments incluso nel repository del codice di questo post come mostrato nel seguente blocco di codice:

# importa una implementazione personalizzata di Experiments Callback
from smexperiments_callback import SageMakerExperimentsCallback......
# Crea un'istanza di Trainer con il callback di SageMaker Experiments
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=validation_dataset,
    data_collator=default_data_collator,
    callbacks=[SageMakerExperimentsCallback] # Aggiungi la nostra funzione di callback per Experiments Plus
)

Questo callback registrerà automaticamente le seguenti informazioni in SageMaker Experiments come parte dell’esecuzione dell’addestramento:

  • Parametri di addestramento e iperparametri
  • Perdita di addestramento e validazione del modello a passo, epoca e finale
  • Artefatti di input e output del modello (data set di addestramento, data set di validazione, posizione di output del modello, debugger di addestramento e altro ancora)

Il grafico seguente mostra esempi dei grafici che è possibile visualizzare utilizzando tali informazioni.

In questo modo è possibile confrontare facilmente più esecuzioni utilizzando la funzione di analisi di SageMaker Experiments. È possibile selezionare le esecuzioni degli esperimenti da confrontare e i grafici di confronto saranno automaticamente generati.

Registra i modelli aggiustati nel Registro Modelli Collezioni

Registro Modelli Collezioni è una funzionalità di SageMaker Registro Modelli che consente di raggruppare modelli registrati tra loro e di organizzarli in gerarchie per migliorare la scoperta dei modelli su larga scala. Utilizzeremo il Registro Modelli Collezioni per monitorare il modello di base e le varianti aggiustate.

Metodo di copia del modello completo

Il primo metodo combina il modello di base e l’adattatore LoRA e salva il modello completo aggiustato. Il seguente codice illustra il processo di fusione del modello e salva il modello combinato utilizzando model.save_pretrained().

if args.merge_weights:
    trainer.model.save_pretrained(temp_dir, safe_serialization=False)
# liberare memoria
del model
del trainer
torch.cuda.empty_cache()
from peft import AutoPeftModelForCausalLM
# carica il modello PEFT in fp16
model = AutoPeftModelForCausalLM.from_pretrained(
    temp_dir,
    low_cpu_mem_usage=True,
    torch_dtype=torch.float16,
)
# Fonde il modello LoRA e il modello di base e salva
model = model.merge_and_unload()
model.save_pretrained(
    args.sm_model_dir, safe_serialization=True, max_shard_size="2GB"
)

La combinazione dell’adattatore LoRA e del modello di base in un unico artefatto di modello, dopo il processo di aggiustamento, ha vantaggi e svantaggi. Il modello combinato è autonomo e può essere gestito e distribuito in modo indipendente senza la necessità del modello di base originale. Il modello può essere monitorato come una propria entità con un nome di versione che riflette il modello di base e i dati di aggiustamento. Possiamo adottare una nomenclatura che utilizzi il nome del base_model_name + dataset_name aggiustato per organizzare i gruppi di modelli. Facoltativamente, le collezioni di modelli possono associare i modelli originali e quelli aggiustati, ma questo potrebbe non essere necessario poiché il modello combinato è indipendente. Il frammento di codice seguente mostra come registrare il modello aggiustato.

# Variabili per il gruppo dei pacchetti di modelli
ft_package_group_name = f"{model_id.replace('/', '--')}-{dataset_name}"
ft_package_group_desc = "QLoRA per il modello Mikael110/llama-2-7b-{dataset_name}-fp16"
.........
# Dizionario di input per il gruppo dei pacchetti di modelli
model_package_group_input_dict = {
    "ModelPackageGroupName" : ft_package_group_name,
    "ModelPackageGroupDescription" : ft_package_group_desc,
    "Tags": ft_tags
}
# Creazione del gruppo dei pacchetti di modelli
create_model_pacakge_group_response = sm_client.create_model_package_group(**model_package_group_input_dict)

Puoi utilizzare l’estimatore di addestramento per registrare il modello nel Model Registry.

inference_image_uri = sagemaker.image_uris.retrieve(    "djl-deepspeed", region=region, version="0.23.0")print(f"L'immagine che verrà utilizzata è ---- > {inference_image_uri}")model_package = huggingface_estimator.register(    content_types=["application/json"],    response_types=["application/json"],    inference_instances=[        "ml.p2.16xlarge", .........    ],    image_uri = inference_image_uri,    customer_metadata_properties = {"training-image-uri": huggingface_estimator.training_image_uri()},  #Salva l'URL dell'immagine di addestramento    model_package_group_name=ft_model_pkg_group_name,    approval_status="Approved")model_package_arn = model_package.model_package_arnprint("Model Package ARN : ", model_package_arn)

Dal Model Registry, puoi recuperare il pacchetto del modello e distribuire direttamente quel modello.

endpoint_name = f"{name_from_base(model_group_for_base)}-endpoint"model_package.deploy(    initial_instance_count=1,    instance_type="ml.g5.12xlarge",    endpoint_name=endpoint_name)

Tuttavia, ci sono degli svantaggi in questo approccio. La combinazione dei modelli porta a una inefficienza di archiviazione e ridondanza poiché il modello di base viene duplicato in ogni versione modificata. Man mano che la dimensione del modello e il numero delle versioni modificate aumentano, ciò inflaziona in modo esponenziale le esigenze di archiviazione. Prendendo ad esempio il modello llama2 7b, il modello di base è di circa 13 GB e il modello fine-tuned è di 13,6 GB. Dopo ogni fine tuning, è necessario duplicare il 96% del modello. Inoltre, distribuire e condividere file di modelli molto grandi diventa più difficile e comporta sfide operative poiché il costo di trasferimento e gestione dei file aumenta con l’aumento delle dimensioni del modello e dei lavori di fine-tuning.

Metodo separato di adattatore e metodo di base

Il secondo metodo si concentra sulla separazione dei pesi di base e dei pesi dell’adattatore salvandoli come componenti di modello separati e caricandoli in modo sequenziale durante l’esecuzione.

    ..    ..    ..    else:           # salva il modello finetuned LoRA e quindi il tokenizer per l'inf 
    trainer.model.save_pretrained(            args.sm_model_dir,             safe_serialization=True        )    tokenizer.save_pretrained(        args.sm_model_dir    )

Salvare i pesi di base e dell’adattatore ha vantaggi e svantaggi, simili al metodo di copia del modello completo. Un vantaggio è che può risparmiare spazio di archiviazione. I pesi di base, che sono il componente più grande di un modello modificato, vengono salvati solo una volta e possono essere riutilizzati con altri pesi dell’adattatore che sono ottimizzati per compiti diversi. Ad esempio, i pesi di base di Llama2-7B sono di circa 13 GB, ma ogni attività di fine-tuning ha bisogno di circa 0,6 GB di pesi dell’adattatore, quindi si ha un risparmio di spazio del 95%. Un altro vantaggio è che i pesi di base possono essere gestiti separatamente dai pesi dell’adattatore utilizzando un registro dei modelli che contiene solo i pesi di base. Questo può essere utile per i domini SageMaker che funzionano in modalità solo VPC senza un gateway Internet, poiché i pesi di base possono essere accessibili senza dover passare attraverso Internet.

Creare un gruppo di pacchetti di modelli per i pesi di base

### Creare un gruppo di pacchetti di modelli       base_package_group_name = model_id.replace('/', '--')base_package_group_desc = "Origine: https://huggingface.co/Mikael110/llama-2-7b-guanaco-fp16".........model_package_group_input_dict = {    "ModelPackageGroupName" : base_package_group_name,    "ModelPackageGroupDescription" : base_package_group_desc,    "Tags": base_tags}create_model_pacakge_group_response = sm_client.create_model_package_group(**model_package_group_input_dict)>>>Creato ModelPackageGroup Arn : arn:aws:sagemaker:us-west-2:376678947624:model-package-group/Mikael110--llama-2-7b-guanaco-fp16.........### Registrare i pesi del modello di base dall'import sagemaker.huggingface import HuggingFaceModel# Creare la classe Hugging Face Modelhuggingface_model = HuggingFaceModel(    transformers_version='4.28',    pytorch_version='2.0',    py_version='py310',    model_data=model_data_uri, # questo è un percorso S3 ai tuoi pesi di base in formato *.tar.gz    role=role,)_response = huggingface_model.register(    content_types=["application/json"],    response_types=["application/json"],    inference_instances=[    "ml.p2.16xlarge",    ...    ],    transform_instances=[    "ml.p2.16xlarge",    ...    ],    model_package_group_name=base_model_pkg_group_name,    approval_status="Approved" )

Crea un gruppo di pacchetti di modelli per i pesi di QLoRA

Il codice seguente mostra come contrassegnare i pesi di QLoRA con il tipo di set di dati/task e registrare i pesi delta aggiornati in un registro separato del modello e tenere traccia dei pesi delta in modo separato.

### Crea un gruppo di pacchetti di modelli per i pesi deltaft_package_group_name = f"{model_id.replace('/', '--')}-sql-ottimizzati"ft_package_group_desc = "QLoRA per il modello Mikael110/llama-2-7b-guanaco-fp16"ft_tags = [    {    "Chiave": "TipoModello",    "Valore": "QLoRAModello"    },    {    "Chiave": "Ottimizzati",    "Valore": "Vero"    },    {    "Chiave": "SetDatiOrigine",    "Valore": f"{dataset_name}"    }]model_package_group_input_dict = {    "NomeGruppoPacchettoModello" : ft_package_group_name,    "DescrizioneGruppoPacchettoModello" : ft_package_group_desc,    "Tags": ft_tags}create_model_pacakge_group_response = sm_client.create_model_package_group(**model_package_group_input_dict)print(f'Creato ModelPackageGroup Arn : {create_model_pacakge_group_response["ModelPackageGroupArn"]}')ft_model_pkg_group_name = create_model_pacakge_group_response["ModelPackageGroupArn"]>>> Creato ModelPackageGroup Arn : arn:aws:sagemaker:us-east-1:811828458885:model-package-group/mikael110--llama-2-7b-guanaco-fp16-finito-sql.........### Registra i pesi delta del modello QLoRAhuggingface_model = ModelloHuggingFace(    transformers_version='4.28',    pytorch_version='2.0',      py_version='py310',    model_data="s3://sagemaker-us-east-1-811828458885/huggingface-qlora-2308180454/output/model.tar.gz", OPPURE #huggingface_estimator.model_data    role=role,)_response = huggingface_model.register(    content_types=["application/json"],    response_types=["application/json"],    inference_instances=[    "ml.p2.16xlarge",    ...    ],    transform_instances=[    "ml.p2.16xlarge",    ...    ],    model_package_group_name=ft_model_pkg_group_name,    stato_approvazione="Approvato")>>>Stato creazione raccolta modelli: {'gruppi_aggiunti': ['arn:aws:sagemaker:us-east-1:811828458885:model-package-group/mikael110--llama-2-7b-guanaco-fp16-finito-sql'], 'fallimento': []}

Il frammento seguente mostra una vista dal Registro del modello in cui i modelli sono divisi in pesi di base e pesi ottimizzati.

Gestire modelli, set di dati e task per gli LLM iper-personalizzati può diventare rapidamente travolgente. Le raccolte del Registro del modello di SageMaker possono aiutarti a raggruppare i modelli correlati e organizzarli in una gerarchia per migliorare la scoperta del modello. Questo rende più facile tracciare le relazioni tra i pesi di base, i pesi dell’adattatore e i set di dati di sintonizzazione fine. Puoi anche creare relazioni e collegamenti complessi tra i modelli.

Crea una nuova raccolta e aggiungi i pesi del modello di base a questa raccolta

# crea una raccolta di modellibase_collection = model_collector.create(    collection_name=model_group_for_base # ex: "Modello_Bot_QnA_Cliente_Sito_Web")# Aggiungi i pesi di base al primo livello delle raccolte di modelli, poiché tutti i futuri modelli # verranno tarati dai pesi di base_response = model_collector.add_model_groups(    collection_name=base_collection["Arn"],    model_groups=[base_model_pkg_group_name])print(f"Stato creazione raccolta modelli: {_response}")>>>Stato creazione raccolta modelli: {'gruppi_aggiunti': ['arn:aws:sagemaker:us-west-2:376678947624:model-package-group/Mikael110--llama-2-7b-guanaco-fp16'], 'fallimento': []}
# crea una collezione di modelli per il fine-tuning e collegala alla collezione di basefinetuned_collection = model_collector.create(    collection_name=model_group_for_finetune,    parent_collection_name=model_group_for_base)# aggiungi il gruppo di pacchetti del modello adattato al fine-tuning alla nuova collezione del fine-tuning_response = model_collector.add_model_groups(    collection_name=model_group_for_finetune,    model_groups=[ft_model_pkg_group_name])print(f"Stato di creazione della collezione di modelli: {_response}")>>>Stato di creazione della collezione di modelli: {'added_groups': ['arn:aws:sagemaker:us-east-1:811828458885:model-package-group/mikael110--llama-2-7b-guanaco-fp16-finetuned-sql'], 'failure': []}

Ciò comporta una gerarchia di collezioni collegate per tipo di modello/compito e il dataset utilizzato per il fine-tuning del modello di base.

Questo metodo di separazione dei modelli di base e adattatori ha alcuni svantaggi. Uno svantaggio è la complessità nel rilasciare il modello. Poiché ci sono due artefatti di modelli separati, sono necessari passaggi aggiuntivi per ripacchettizzare il modello anziché rilasciarlo direttamente dal Registro dei modelli. Nell’esempio di codice seguente, scarica e ripacchetta la versione più recente del modello di base.

!aws s3 cp {base_model_package.model_data} .!tar -xvf {model_tar_filename} -C ./deepspeed/!mv ./deepspeed/{model_id} ./deepspeed/base!rm -rf ./deepspeed/{model_id}

Quindi scarica e ripacchetta i pesi dell’adattatore LoRA adattati al fine-tuning più recenti.

!aws s3 cp {LoRA_package.model_data} .!mkdir -p ./deepspeed/lora/!tar -xzf model.tar.gz -C ./deepspeed/lora/

Dal momento che utilizzerai DJL serving con deepspeed per ospitare il modello, la tua directory di inferenza dovrebbe apparire come segue.

deepspeed    |-serving.properties    |-requirements.txt    |-model.py    |-base/        |-...    |-lora/        |-...

Infine, impacchetta il codice di inferenza personalizzato, il modello di base e l’adattatore LoRA in un unico file .tar.gz per il rilascio.

!rm -f model.tar.gz!tar czvf model.tar.gz -C deepspeed .s3_code_artifact_deepspeed = sagemaker_session.upload_data("model.tar.gz", default_bucket, f"{s3_key_prefix}/inference")print(f"Artefatto Co
dice S3 o modello tar per deepspeed caricato su --- > {s3_code_artifact_deepspeed}")

Pulizia

Rimuovi le risorse seguendo le istruzioni nella sezione di pulizia del notebook. Consulta Amazon SageMaker Pricing per i dettagli sul costo delle istanze di inferenza.

Conclusione

In questo post ti abbiamo illustrato le migliori pratiche per la gestione dei modelli fine-tuned LoRA su Amazon SageMaker. Abbiamo coperto due metodi principali: combinare i pesi del modello di base e dell’adattatore in un unico modello autosufficiente e separare i pesi del modello di base e dell’adattatore. Entrambi gli approcci presentano dei compromessi, ma la separazione dei pesi aiuta a ottimizzare lo storage e consente tecniche avanzate di gestione dei modelli come SageMaker Model Registry Collections. Ciò ti permette di costruire gerarchie e relazioni tra i modelli per migliorare l’organizzazione e la fruibilità. Ti incoraggiamo a provare il codice di esempio sul repository GitHub per sperimentare questi metodi tu stesso. Man mano che l’IA generativa progredisce rapidamente, seguire le migliori pratiche di gestione dei modelli ti aiuterà a tracciare gli esperimenti, trovare il modello giusto per il tuo compito e gestire in modo efficiente LLM specializzati su larga scala.

Riferimenti