Modelli e piattaforme di IA

Tracciamento dei Modelli Linguistici di Grande Scala (LLM) con MLflow: Una Guida Completa

mm
Aggiungi Unite.AI alle tue fonti preferite su Google

I Modelli Linguistici di Grande Scala (LLM) stanno crescendo in complessità e scala, rendendo sempre più difficile il tracciamento delle loro prestazioni, esperimenti e distribuzioni. È qui che entra in gioco MLflow – fornendo una piattaforma completa per la gestione dell’intero ciclo di vita dei modelli di apprendimento automatico, compresi gli LLM.

In questa guida approfondita, esploreremo come sfruttare MLflow per tracciare, valutare e distribuire gli LLM. Copriremo tutto, dalle impostazioni dell’ambiente alle tecniche di valutazione avanzate, con molti esempi di codice e best practice lungo la strada.

Funzionalità di MLflow nei Modelli Linguistici di Grande Scala (LLM)

MLflow è diventato uno strumento fondamentale nella comunità di apprendimento automatico e scienza dei dati, specialmente per la gestione del ciclo di vita dei modelli di apprendimento automatico. Quando si tratta di Modelli Linguistici di Grande Scala (LLM), MLflow offre una suite di strumenti robusta che semplifica notevolmente il processo di sviluppo, tracciamento, valutazione e distribuzione di questi modelli. Ecco un panorama di come MLflow funziona all’interno dello spazio LLM e dei benefici che offre agli ingegneri e ai data scientist.

Scopri i componenti principali di MLflow

Tracciamento e Gestione delle Interazioni LLM

Il sistema di tracciamento LLM di MLflow è un miglioramento delle sue capacità di tracciamento esistenti, personalizzato per le esigenze uniche degli LLM. Consente il tracciamento completo delle interazioni del modello, compresi i seguenti aspetti chiave:

  • Parametri: Logging di coppie chiave-valore che dettagliano i parametri di input per l’LLM, come parametri specifici del modello come top_k e temperature. Ciò fornisce contesto e configurazione per ogni esecuzione, garantendo che tutti gli aspetti della configurazione del modello siano catturati.
  • Metriche: Misure quantitative che forniscono informazioni sulle prestazioni e sull’accuratezza dell’LLM. Queste possono essere aggiornate dinamicamente mentre l’esecuzione procede, offrendo insight in tempo reale o post-processo.
  • Previsioni: È cruciale registrare sia gli input inviati all’LLM che le uscite del modello, che vengono archiviate come artifact in formato strutturato per un facile recupero e analisi.
  • Artifact: Oltre alle previsioni, MLflow può archiviare vari file di output come visualizzazioni, modelli serializzati e file di dati strutturati, consentendo una documentazione e un’analisi dettagliate delle prestazioni del modello.

Questo approccio strutturato garantisce che tutte le interazioni con l’LLM siano registrate meticolosamente, fornendo una completa discendenza e un tracciamento di qualità per i modelli di generazione di testo.

Valutazione degli LLM

La valutazione degli LLM presenta sfide uniche a causa della loro natura generativa e della mancanza di un’unica verità di riferimento. MLflow semplifica questo con strumenti di valutazione specializzati progettati per gli LLM. Le caratteristiche chiave includono:

  • Valutazione del modello versatile: Supporta la valutazione di vari tipi di LLM, sia che si tratti di un modello pyfunc MLflow, di un URI che punta a un modello MLflow registrato o di qualsiasi funzione Python che rappresenta il tuo modello.
  • Metriche complete: Offre una gamma di metriche personalizzate per la valutazione degli LLM, comprese sia metriche dipendenti dal modello SaaS (ad esempio, rilevanza della risposta) che metriche basate su funzioni (ad esempio, ROUGE, Flesch Kincaid).
  • Raccolte di metriche predefinite: A seconda del caso d’uso, come la risposta alle domande o la sintesi del testo, MLflow fornisce metriche predefinite per semplificare il processo di valutazione.
  • Creazione di metriche personalizzate: Consente agli utenti di definire e implementare metriche personalizzate per soddisfare esigenze di valutazione specifiche, aumentando la flessibilità e la profondità della valutazione del modello.
  • Valutazione con dataset statici: Consente la valutazione di dataset statici senza specificare un modello, utile per valutazioni rapide senza dover eseguire nuovamente l’inferenza del modello.

Distribuzione e Integrazione

MLflow supporta anche la distribuzione e l’integrazione degli LLM:

  • Server di distribuzione MLflow: Agisce come un’interfaccia unificata per l’interazione con più provider di LLM. Semplifica le integrazioni, gestisce le credenziali in modo sicuro e offre un’esperienza API coerente. Questo server supporta una gamma di modelli fondamentali da vendor SaaS popolari, nonché modelli self-hosted.
  • Endpoint unificato: Facilita il passaggio tra i provider senza modifiche al codice, minimizzando il downtime e aumentando la flessibilità.
  • Visualizzazione dei risultati integrata: Fornisce risultati di valutazione completi, che possono essere accessibili direttamente nel codice o attraverso l’interfaccia utente di MLflow per un’analisi dettagliata.

MLflow è una suite completa di strumenti e integrazioni che lo rende un asset inestimabile per gli ingegneri e i data scientist che lavorano con modelli NLP avanzati.

Impostazione dell’Ambiente

Prima di immergerci nel tracciamento degli LLM con MLflow, impostiamo il nostro ambiente di sviluppo. Avremo bisogno di installare MLflow e diverse altre librerie chiave:

pip install mlflow>=2.8.1
pip install openai
pip install chromadb==0.4.15
pip install langchain==0.0.348
pip install tiktoken
pip install 'mlflow[genai]'
pip install databricks-sdk --upgrade

Dopo l’installazione, è una buona pratica riavviare l’ambiente Python per assicurarsi che tutte le librerie siano caricate correttamente. In un notebook Jupyter, puoi utilizzare:

import mlflow
import chromadb

<p>print(f"Versione MLflow: {mlflow.__version__}")
print(f"Versione ChromaDB: {chromadb.__version__}")

Ciò confermerà le versioni delle librerie chiave che utilizzeremo.

Comprensione delle Capacità di Tracciamento LLM di MLflow

Il sistema di tracciamento LLM di MLflow si basa sulle sue capacità di tracciamento esistenti, aggiungendo funzionalità specificamente progettate per gli aspetti unici degli LLM. Analizziamo i componenti chiave:

Esecuzioni e Esperimenti

In MLflow, un “run” rappresenta una singola esecuzione del codice del modello, mentre un “esperimento” è una raccolta di esecuzioni correlate. Per gli LLM, un run potrebbe rappresentare una singola query o un batch di prompt elaborati dal modello.

Componenti di Tracciamento Chiave

  1. Parametri: Questi sono configurazioni di input per il tuo LLM, come temperatura, top_k o max_tokens. Puoi registrarli utilizzando mlflow.log_param() o mlflow.log_params().
  2. Metriche: Misure quantitative delle prestazioni del tuo LLM, come accuratezza, latenza o punteggi personalizzati. Utilizza mlflow.log_metric() o mlflow.log_metrics() per tracciare queste.
  3. Previsioni: Per gli LLM, è cruciale registrare sia gli input inviati all’LLM che le uscite del modello. MLflow archivia questi come artifact in formato CSV utilizzando mlflow.log_table().
  4. Artifact: Qualsiasi file o dati aggiuntivi relativi all’esecuzione dell’LLM, come checkpoint del modello, visualizzazioni o campioni del dataset. Utilizza mlflow.log_artifact() per archiviare questi.

Vediamo un esempio di base di registrazione di un run LLM:

Questo esempio dimostra la registrazione di parametri, metriche e input/output come artifact di tabella.


import mlflow
import openai

<p>def query_llm(prompt, max_tokens=100):
response = openai.Completion.create(
engine="text-davinci-002",
prompt=prompt,
max_tokens=max_tokens
)
return response.choices[0].text.strip()</p>

<p>with mlflow.start_run():
prompt = "Spiega il concetto di apprendimento automatico in termini semplici."</p>

<p># Registra parametri
mlflow.log_param("model", "text-davinci-002")
mlflow.log_param("max_tokens", 100)</p>

<p># Query l'LLM e registra il risultato
result = query_llm(prompt)
mlflow.log_metric("response_length", len(result))</p>

<p># Registra il prompt e la risposta
mlflow.log_table("prompt_responses", {"prompt": [prompt], "response": [result]})</p>

<p>print(f"Risposta: {result}")

Distribuzione degli LLM con MLflow

MLflow fornisce capacità potenti per la distribuzione degli LLM, rendendo più facile servire i tuoi modelli in ambienti di produzione. Esploriamo come distribuire un LLM utilizzando le funzionalità di distribuzione di MLflow.

Creazione di un Endpoint

Innanzitutto, creeremo un endpoint per il nostro LLM utilizzando il client di distribuzione di MLflow:

import mlflow
from mlflow.deployments import get_deploy_client

<p># Inizializza il client di distribuzione
client = get_deploy_client("databricks")</p>

<p># Definisci la configurazione dell'endpoint
endpoint_name = "llm-endpoint"
endpoint_config = {
"served_entities": [{
"name": "gpt-model",
"external_model": {
"name": "gpt-3.5-turbo",
"provider": "openai",
"task": "llm/v1/completions",
"openai_config": {
"openai_api_type": "azure",
"openai_api_key": "{{secrets/scope/openai_api_key}}",
"openai_api_base": "{{secrets/scope/openai_api_base}}",
"openai_deployment_name": "gpt-35-turbo",
"openai_api_version": "2023-05-15",
},
},
}],
}</p>

<p># Crea l'endpoint
client.create_endpoint(name=endpoint_name, config=endpoint_config)

Questo codice imposta un endpoint per un modello GPT-3.5-turbo utilizzando Azure OpenAI. Nota l’utilizzo di segreti Databricks per la gestione sicura delle chiavi API.

Test dell’Endpoint

Una volta creato l’endpoint, possiamo testarlo:

&lt;div class="relative flex flex-col rounded-lg"&gt;

<p>response = client.predict(
endpoint=endpoint_name,
inputs={"prompt": "Spiega il concetto di reti neurali in breve.", "max_tokens": 100,},)</p>

print(response)

Ciò invierà un prompt al nostro modello distribuito e restituirà la risposta generata.

Valutazione degli LLM con MLflow

La valutazione è cruciale per comprendere le prestazioni e il comportamento degli LLM. MLflow fornisce strumenti completi per la valutazione degli LLM, comprese metriche personalizzate e predefinite.

Preparazione dell’LLM per la Valutazione

Per valutare il tuo LLM con mlflow.evaluate(), il tuo modello deve essere in una delle seguenti forme:

  1. Un’istanza di mlflow.pyfunc.PyFuncModel o un URI che punta a un modello MLflow registrato.
  2. Una funzione Python che prende stringhe in input e restituisce una singola stringa.
  3. Un URI di endpoint di distribuzione MLflow.
  4. Imposta model=None e includi le uscite del modello nei dati di valutazione.

Vediamo un esempio utilizzando un modello MLflow registrato:

import mlflow
import openai

<p>with mlflow.start_run():
system_prompt = "Rispondi alla seguente domanda in modo conciso."
logged_model_info = mlflow.openai.log_model(
model="gpt-3.5-turbo",
task=openai.chat.completions,
artifact_path="model",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "{question}"},
],
)</p>

<p># Prepara dati di valutazione
eval_data = pd.DataFrame({
"question": ["Che cosa è l'apprendimento automatico?", "Spiega le reti neurali."],
"ground_truth": [
"L'apprendimento automatico è un subset dell'AI che consente ai sistemi di apprendere e migliorare dall'esperienza senza programmazione esplicita.",
"Le reti neurali sono sistemi di calcolo ispirati alle reti neurali biologiche, composte da nodi interconnessi che elaborano e trasmettono informazioni."
]
})</p>

<p># Valuta il modello
results = mlflow.evaluate(
logged_model_info.model_uri,
eval_data,
targets="ground_truth",
model_type="question-answering",
)</p>

<p>print(f"Metriche di valutazione: {results.metrics}")

Questo esempio registra un modello OpenAI, prepara i dati di valutazione e quindi valuta il modello utilizzando le metriche predefinite di MLflow per i compiti di risposta alle domande.

Metriche di Valutazione Personalizzate

MLflow consente di definire metriche personalizzate per la valutazione degli LLM. Ecco un esempio di creazione di una metrica personalizzata per valutare la professionalità delle risposte:

from mlflow.metrics.genai import EvaluationExample, make_genai_metric

<p>professionalità = make_genai_metric(
name="professionalità",
definition="Misura dello stile di comunicazione formale e appropriato.",
grading_prompt=(
"Valuta la professionalità della risposta su una scala da 0 a 4:\n"
"0: Estremamente informale o inappropriato\n"
"1: Informale ma rispettoso\n"
"2: Moderatamente formale\n"
"3: Professionale e appropriato\n"
"4: Altamente formale e esperto"
),
examples=[
EvaluationExample(
input="Che cosa è MLflow?",
output="MLflow è come il tuo toolkit di quartiere per la gestione dei progetti di apprendimento automatico. È super cool!",
score=1,
justification="La risposta è informale e utilizza un linguaggio non formale."
),
EvaluationExample(
input="Che cosa è MLflow?",
output="MLflow è una piattaforma open-source per il ciclo di vita dell'apprendimento automatico, compresa la sperimentazione, la riproducibilità e la distribuzione.",
score=4,
justification="La risposta è formale, concisa e professionalmente formulata."
)
],
model="openai:/gpt-3.5-turbo-16k",
parameters={"temperature": 0.0},
aggregations=["mean", "variance"],
greater_is_better=True,
)</p>

<p># Utilizza la metrica personalizzata nella valutazione
results = mlflow.evaluate(
logged_model_info.model_uri,
eval_data,
targets="ground_truth",
model_type="question-answering",
extra_metrics=[professionalità]
)</p>

<p>print(f"Punteggio di professionalità: {results.metrics['professionalità_mean']}")

Questa metrica personalizzata utilizza GPT-3.5-turbo per valutare la professionalità delle risposte, dimostrando come sia possibile sfruttare gli LLM stessi per la valutazione.

Tecniche di Valutazione Avanzate per gli LLM

Man mano che gli LLM diventano più sofisticati, anche le tecniche di valutazione diventano più avanzate. Esploriamo alcune tecniche di valutazione avanzate utilizzando MLflow.

Valutazione di Generazione con Recupero (RAG)

I sistemi RAG combinano la potenza dei modelli di recupero e generazione. La valutazione dei sistemi RAG richiede la valutazione sia del componente di recupero che di quello di generazione. Ecco come impostare un sistema RAG e valutarlo utilizzando MLflow:

from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI

<p># Carica e preprocessa i documenti
loader = WebBaseLoader(["https://mlflow.org/docs/latest/index.html"])
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Crea un archivio vettoriale
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(texts, embeddings)</p>

<p># Crea una catena RAG
llm = OpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vectorstore.as_retriever(),
return_source_documents=True
)</p>

<p># Funzione di valutazione
def evaluate_rag(question):
result = qa_chain({"query": question})
return result["result"], [doc.page_content for doc in result["source_documents"]]</p>

<p># Prepara dati di valutazione
eval_questions = [
"Che cosa è MLflow?",
"Come gestisce MLflow il tracciamento degli esperimenti?",
"Quali sono i principali componenti di MLflow?",
]</p>

<p># Valuta utilizzando MLflow
with mlflow.start_run():
for question in eval_questions:
answer, sources = evaluate_rag(question)</p>

<p>mlflow.log_param(f"question", question)
mlflow.log_metric("num_sources", len(sources))
mlflow.log_text(answer, f"answer_{question}.txt")</p>

<p>for i, source in enumerate(sources):
mlflow.log_text(source, f"source_{question}_{i}.txt")</p>

<p># Registra metriche personalizzate
mlflow.log_metric("avg_sources_per_question", sum(len(evaluate_rag(q)[1]) for q in eval_questions) / len(eval_questions))

Questo esempio imposta un sistema RAG utilizzando LangChain e Chroma, quindi lo valuta registrando domande, risposte, fonti recuperate e metriche personalizzate in MLflow.

Valutazione della Strategia di Suddivisione

Il modo in cui si suddividono i documenti può avere un impatto significativo sulle prestazioni del RAG. MLflow può aiutare a valutare diverse strategie di suddivisione:

import mlflow
from langchain.text_splitter import CharacterTextSplitter, TokenTextSplitter

<p>def evaluate_chunking_strategy(documents, chunk_size, chunk_overlap, splitter_class):
splitter = splitter_class(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
chunks = splitter.split_documents(documents)</p>

<p>with mlflow.start_run():
mlflow.log_param("chunk_size", chunk_size)
mlflow.log_param("chunk_overlap", chunk_overlap)
mlflow.log_param("splitter_class", splitter_class.__name__)</p>

<p>mlflow.log_metric("num_chunks", len(chunks))
mlflow.log_metric("avg_chunk_length", sum(len(chunk.page_content) for chunk in chunks) / len(chunks))</p>

<p># Valuta le prestazioni di recupero (semplificato)
correct_retrievals = sum(1 for _ in range(100) if simulate_retrieval(chunks))
mlflow.log_metric("retrieval_accuracy", correct_retrievals / 100)</p>

<p># Valuta diverse strategie
for chunk_size in [500, 1000, 1500]:
for chunk_overlap in [0, 50, 100]:
for splitter_class in [CharacterTextSplitter, TokenTextSplitter]:
evaluate_chunking_strategy(documents, chunk_size, chunk_overlap, splitter_class)</p>

<p># Confronta i risultati
best_run = mlflow.search_runs(order_by=["metrics.retrieval_accuracy DESC"]).iloc[0]
print(f"Strategia di suddivisione migliore: {best_run['params.splitter_class']} con dimensione {best_run['params.chunk_size']} e sovrapposizione {best_run['params.chunk_overlap']}")

Questo script valuta diverse combinazioni di dimensioni di chunk, sovrapposizioni e metodi di suddivisione, registrando i risultati in MLflow per un facile confronto.

Visualizzazione dei Risultati di Valutazione degli LLM

MLflow fornisce vari modi per visualizzare i risultati di valutazione degli LLM. Ecco alcune tecniche:

Utilizzo dell’Interfaccia Utente di MLflow

Dopo aver eseguito le valutazioni, puoi utilizzare l’interfaccia utente di MLflow per visualizzare i risultati:

  1. Avvia l’interfaccia utente di MLflow: mlflow ui
  2. Apri un browser web e naviga fino a http://localhost:5000
  3. Seleziona il tuo esperimento e le tue esecuzioni per visualizzare metriche, parametri e artifact

Visualizzazioni Personalizzate

Puoi creare visualizzazioni personalizzate dei risultati di valutazione utilizzando librerie come Matplotlib o Plotly, quindi registrarle come artifact:

import matplotlib.pyplot as plt
import mlflow

<p>def plot_metric_comparison(metric_name, run_ids):
plt.figure(figsize=(10, 6))
for run_id in run_ids:
run = mlflow.get_run(run_id)
metric_values = mlflow.get_metric_history(run_id, metric_name)
plt.plot([m.step for m in metric_values], [m.value for m in metric_values], label=run.data.tags.get("mlflow.runName", run_id))</p>

<p>plt.title(f"Confronto di {metric_name}")
plt.xlabel("Step")
plt.ylabel(metric_name)
plt.legend()</p>

<p># Salva e registra il grafico
plt.savefig(f"{metric_name}_comparison.png")
mlflow.log_artifact(f"{metric_name}_comparison.png")</p>

<p># Utilizzo
with mlflow.start_run():
plot_metric_comparison("answer_relevance", ["run_id_1", "run_id_2", "run_id_3"])

Questa funzione crea un grafico a linee che confronta una specifica metrica tra più esecuzioni e lo registra come artifact.

Alternative a MLflow Open Source

Esistono numerose alternative a MLflow open source per la gestione dei flussi di lavoro di apprendimento automatico, ognuna con caratteristiche e integrazioni uniche.

MLflow Gestito da Databricks

MLflow gestito, ospitato da Databricks, fornisce le funzionalità principali di MLflow open source ma con vantaggi aggiuntivi come l’integrazione senza soluzione di continuità con l’ecosistema di Databricks, funzionalità di sicurezza avanzate e infrastruttura gestita. Ciò lo rende una scelta eccellente per le organizzazioni che richiedono sicurezza e scalabilità robuste.

Azure Machine Learning

Azure Machine Learning offre una soluzione di apprendimento automatico end-to-end sulla piattaforma cloud di Microsoft. Fornisce la compatibilità con componenti MLflow come il registro dei modelli e il tracciamento degli esperimenti, sebbene non sia basato su MLflow.

Piattaforme ML Dedicati

Diverse aziende forniscono prodotti ML gestiti con caratteristiche diverse:

  • neptune.ai: Si concentra sul tracciamento degli esperimenti e sulla gestione dei modelli.
  • Weights & Biases: Offre un tracciamento estensivo degli esperimenti, la versione dei dataset e gli strumenti di collaborazione.
  • Comet ML: Fornisce il tracciamento degli esperimenti, il monitoraggio della produzione dei modelli e la registrazione dei dati.
  • Valohai: Si specializza nelle pipeline di apprendimento automatico e nell’orchestrazione.

Metaflow

Metaflow, sviluppato da Netflix (NFLX ), è un framework open-source progettato per orchestrare i flussi di lavoro dei dati e le pipeline di apprendimento automatico. Sebbene eccella nella gestione di distribuzioni su larga scala, manca di funzionalità di tracciamento degli esperimenti e gestione dei modelli complete rispetto a MLflow.

Amazon SageMaker e Google’s Vertex AI

Sia Amazon SageMaker (AMZN ) che Google’s Vertex AI (GOOGL ) forniscono soluzioni MLOps end-to-end integrate nelle loro piattaforme cloud. Questi servizi offrono strumenti robusti per la costruzione, l’addestramento e la distribuzione di modelli di apprendimento automatico su larga scala.

Confronto Dettagliato

MLflow Gestito vs. MLflow Open Source

MLflow gestito da Databricks offre diversi vantaggi rispetto alla versione open source, tra cui:

  • Impostazione e Distribuzione: L’integrazione senza soluzione di continuità con Databricks riduce il tempo di impostazione e lo sforzo.
  • Scalabilità: In grado di gestire carichi di lavoro di apprendimento automatico su larga scala con facilità.
  • Sicurezza e Gestione: Funzionalità di sicurezza out-of-the-box come il controllo di accesso basato su ruoli (RBAC) e la crittografia dei dati.
  • Integrazione: Integrazione profonda con i servizi di Databricks, migliorando l’interoperabilità e la funzionalità.
  • Archiviazione e Backup dei Dati: Strategie di backup automatiche per garantire la sicurezza e l’affidabilità dei dati.
  • Costo: Gli utenti pagano per la piattaforma, l’archiviazione e le risorse di calcolo.
  • Supporto e Manutenzione: Supporto e manutenzione dedicati forniti da Databricks.

Conclusione

Il tracciamento dei Modelli Linguistici di Grande Scala con MLflow fornisce un framework robusto per la gestione delle complessità dello sviluppo, della valutazione e della distribuzione degli LLM. Seguendo le best practice e sfruttando le funzionalità avanzate descritte in questa guida, puoi creare esperimenti LLM più organizzati, riproducibili e informativi.

Ricorda che il campo degli LLM sta evolvendo rapidamente e che nuove tecniche di valutazione e tracciamento stanno emergendo costantemente. Mantieniti aggiornato con le ultime versioni di MLflow e le ricerche sugli LLM per raffinare costantemente i tuoi processi di tracciamento e valutazione.

Mentre applichi queste tecniche nei tuoi progetti, svilupperai una comprensione più profonda del comportamento e delle prestazioni dei tuoi LLM, portando a modelli linguistici più efficaci e affidabili.

Ho trascorso gli ultimi cinque anni immergendomi nel mondo affascinante del Machine Learning e del Deep Learning. La mia passione e la mia esperienza mi hanno portato a contribuire a oltre 50 progetti di ingegneria del software diversi, con un focus particolare su AI/ML. La mia curiosità in corso mi ha anche portato verso l'elaborazione del linguaggio naturale, un campo che sono ansioso di esplorare ulteriormente.