AI-modeller och plattformar

Spåra Stora Språkmodeller med MLflow: En Komplett Guide

mm
Lägg till Unite.AI bland dina föredragna källor på Google
div]:bg-bg-300 [&_pre]:-mr-4 md:[&_pre]:-mr-9″>

När Stora Språkmodeller (LLM) växer i komplexitet och omfattning, blir det allt svårare att spåra deras prestanda, experiment och distributioner. Här kommer MLflow in – som tillhandahåller en omfattande plattform för att hantera hela livscykeln för maskinlärningsmodeller, inklusive LLM.

I den här djupgående guiden kommer vi att utforska hur man kan utnyttja MLflow för att spåra, utvärdera och distribuera LLM. Vi kommer att täcka allt från att konfigurera din miljö till avancerade utvärderingstekniker, med många kodexempel och bästa praxis längs vägen.

Funktionalitet av MLflow i Stora Språkmodeller (LLM)

MLflow har blivit ett avgörande verktyg i maskinlärnings- och data science-samhället, särskilt för att hantera livscykeln för maskinlärningsmodeller. När det gäller Stora Språkmodeller (LLM) erbjuder MLflow en robust uppsättning verktyg som avsevärt förenklar processen att utveckla, spåra, utvärdera och distribuera dessa modeller. Här är en översikt av hur MLflow fungerar inom LLM-området och de fördelar det ger till ingenjörer och data scientists.

Lär dig om de grundläggande komponenterna i MLflow

Spåra och Hantera LLM-interaktioner

MLflows LLM-spårningssystem är en utökning av dess befintliga spårningsfunktioner, anpassade till de unika behoven hos LLM. Det möjliggör omfattande spårning av modellinteraktioner, inklusive följande nyckelaspekter:

  • Parametrar: Logga nyckel-värdepar som detaljerar inmatningsparametrarna för LLM, såsom modellspecifika parametrar som top_k och temperature. Detta ger sammanhang och konfiguration för varje körning, vilket säkerställer att alla aspekter av modellens konfiguration fångas.
  • Mätvärden: Kvantitativa mått som ger insikt i LLM:s prestanda och noggrannhet. Dessa kan uppdateras dynamiskt när körningen fortskrider, vilket erbjuder realtids- eller efterbearbetningsinsikter.
  • Förutsägelser: Logga inmatningsprompt och modellens utdata, som lagras som artefakter i en strukturerad format för enkel återvinning och analys.
  • Artefakter: Utöver förutsägelser kan MLflow lagra olika utdatafiler, såsom visualiseringar, serialiserade modeller och strukturerade datafiler, vilket möjliggör detaljerad dokumentation och analys av modellens prestanda.

Denna strukturerade metod säkerställer att alla interaktioner med LLM:n noggrant dokumenteras, vilket ger en omfattande linje och kvalitetsspårning för textgenererande modeller.

Utvärdering av LLM

Utvärdering av LLM presenterar unika utmaningar på grund av deras generativa natur och bristen på en enda grundläggande sanning. MLflow förenklar detta med specialiserade utvärderingsverktyg utformade för LLM. Nyckelfunktioner inkluderar:

  • Mångsidig modellutvärdering: Stödjer utvärdering av olika typer av LLM, antingen som en MLflow pyfunc-modell, en URI som pekar på en registrerad MLflow-modell eller en Python-funktion som representerar din modell.
  • Omfattande mätvärden: Erbjuder ett urval av mätvärden anpassade för LLM-utvärdering, inklusive både SaaS-modellbaserade mätvärden (t.ex. svarshänsyn) och funktionsbaserade mätvärden (t.ex. ROUGE, Flesch Kincaid).
  • Fördefinierade mätvärdesamlingar: Beroende på användningsfallet, såsom frågesvar eller textsammanfattning, erbjuder MLflow fördefinierade mätvärden för att förenkla utvärderingsprocessen.
  • Anpassad mätvärdeskapning: Tillåter användare att definiera och implementera anpassade mätvärden för att tillgodose specifika utvärderingsbehov, vilket förbättrar flexibiliteten och djupet i modellutvärderingen.
  • Utvärdering med statiska dataset: Möjliggör utvärdering av statiska dataset utan att ange en modell, vilket är användbart för snabba bedömningar utan att köra modellinferens igen.

Distribution och Integration

MLflow stöder också smidig distribution och integration av LLM:

  • MLflow-distributionsserver: Fungerar som ett enhetligt gränssnitt för interaktion med flera LLM-leverantörer. Det förenklar integrationer, hanterar autentiseringsuppgifter på ett säkert sätt och erbjuder en konsekvent API-upplevelse. Denna server stöder en rad grundläggande modeller från populära SaaS-leverantörer samt självvärd modeller.
  • Enhetlig slutpunkt: Underlättar enkel växling mellan leverantörer utan kodändringar, vilket minimerar driftstopp och förbättrar flexibiliteten.
  • Integrerad resultatsvy: Tillhandahåller omfattande utvärderingsresultat, som kan nås direkt i koden eller via MLflow UI för detaljerad analys.

MLflow är en omfattande uppsättning verktyg och integrationer som gör det till en ovärderlig tillgång för ingenjörer och data scientists som arbetar med avancerade NLP-modeller.

Konfigurera Din Miljö

Innan vi dyker in i att spåra LLM med MLflow, låt oss konfigurera vår utvecklingsmiljö. Vi behöver installera MLflow och flera andra viktiga bibliotek:

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

Efter installation är det en bra praxis att starta om din Python-miljö för att säkerställa att alla bibliotek är korrekt laddade. I en Jupyter-anteckningsbok kan du använda:

import mlflow
import chromadb

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

Detta kommer att bekräfta versionerna av de viktiga biblioteken vi kommer att använda.

Förstå MLflows LLM-spårningsförmågor

MLflows LLM-spårningssystem bygger på dess befintliga spårningsförmågor, med tillägg av funktioner specifikt utformade för de unika aspekterna av LLM. Låt oss bryta ner de viktigaste komponenterna:

Körningar och Experiment

I MLflow representerar en “körning” en enda körning av din modellkod, medan ett “experiment” är en samling relaterade körningar. För LLM kan en körning representera en enda fråga eller en batch med prompt som bearbetas av modellen.

Viktiga Spårningskomponenter

  1. Parametrar: Dessa är inmatningskonfigurationer för din LLM, såsom temperatur, top_k eller max_token. Du kan logga dessa med mlflow.log_param() eller mlflow.log_params().
  2. Mätvärden: Kvantitativa mått på din LLM:s prestanda, som noggrannhet, latens eller anpassade poäng. Använd mlflow.log_metric() eller mlflow.log_metrics() för att spåra dessa.
  3. Förutsägelser: För LLM är det viktigt att logga både inmatningsprompt och modellens utdata. MLflow lagrar dessa som artefakter i CSV-format med mlflow.log_table().
  4. Artefakter: Alla ytterligare filer eller data relaterade till din LLM-körning, såsom modellcheckpunkter, visualiseringar eller datamängdsprover. Använd mlflow.log_artifact() för att lagra dessa.

Låt oss titta på ett grundläggande exempel på att logga en LLM-körning:

Detta exempel demonstrerar loggning av parametrar, mätvärden och in-/utdata som en tabellartefakt.


import mlflow
import openai

<p>def query_llm(prompt, max_tokens=100):</p>

<p> 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():</p>

<p> prompt = "Förklara konceptet maskinlärning på ett enkelt sätt."</p>

<p> # Logga parametrar
mlflow.log_param("modell", "text-davinci-002")
mlflow.log_param("max_tokens", 100)</p>

<p> # Fråga LLM och logga resultat
result = query_llm(prompt)
mlflow.log_metric("svars_längd", len(result))</p>

<p> # Logga prompt och svar
mlflow.log_table("prompt_svar", {"prompt": [prompt], "svar": [result]})</p>

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

Distribuera LLM med MLflow

MLflow erbjuder kraftfulla funktioner för att distribuera LLM, vilket gör det enklare att tjäna dina modeller i produktionsmiljöer. Låt oss utforska hur man distribuerar en LLM med MLflows distributionsfunktioner.

Skapa en Slutpunkt

Först kommer vi att skapa en slutpunkt för vår LLM med MLflows distributionsklient:

import mlflow
from mlflow.deployments import get_deploy_client

<p># Initiera distributionsklienten
client = get_deploy_client("databricks")</p>

<p># Definiera slutpunktskonfigurationen
slutpunktsnamn = "llm-slutpunkt"
slutpunktskonfig = {
"served_entities": [{
"name": "gpt-modell",
"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># Skapa slutpunkten
client.create_endpoint(name=slutpunktsnamn, config=slutpunktskonfig)

Denna kod konfigurerar en slutpunkt för en GPT-3.5-turbo-modell med Azure OpenAI. Observera användningen av Databricks-hemligheter för säker API-nyckelhantering.

Testa Slutpunkten

När slutpunkten är skapad kan vi testa den:

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

<p>response = client.predict(
endpoint=slutpunktsnamn,
inputs={"prompt": "Förklara konceptet neuronnät på ett kort sätt.", "max_tokens": 100,},
)</p>

print(response)

Detta kommer att skicka en prompt till vår distribuerade modell och returnera den genererade responsen.

Utvärdera LLM med MLflow

Utvärdering är avgörande för att förstå prestanda och beteende hos dina LLM. MLflow erbjuder omfattande verktyg för att utvärdera LLM, inklusive både inbyggda och anpassade mätvärden.

Förbereda Din LLM för Utvärdering

För att utvärdera din LLM med mlflow.evaluate() måste din modell vara i en av följande former:

  1. En mlflow.pyfunc.PyFuncModel-instans eller en URI som pekar på en loggad MLflow-modell.
  2. En Python-funktion som tar stränginmatningar och returnerar en enda sträng.
  3. En MLflow-distributions-slutpunkts-URI.
  4. Ange modell=None och inkludera modellutdata i utvärderingsdata.

Låt oss titta på ett exempel som använder en loggad MLflow-modell:

import mlflow
import openai

<p>with mlflow.start_run():</p>

<p> system_prompt = "Svara på följande fråga kortfattat."
logged_model_info = mlflow.openai.log_model(
model="gpt-3.5-turbo",
task=openai.chat.completions,
artifact_path="modell",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "{fråga}"},
],
)</p>

<p> # Förbered utvärderingsdata
utvärderingsdata = pd.DataFrame({
"fråga": ["Vad är maskinlärning?", "Förklara neuronnät."],
"grund_sanning": [
"Maskinlärning är en undergrupp till AI som möjliggör system att lära och förbättra från erfarenhet utan explicit programmering.",
"Neuronnät är beräkningsystem inspirerade av biologiska neuronnät, bestående av sammanlänkade noder som bearbetar och överför information.",
]
})</p>

<p> # Utvärdera modellen
result = mlflow.evaluate(
logged_model_info.model_uri,
utvärderingsdata,
targets="grund_sanning",
model_type="frågesvar",
)</p>

<p>print(f"Utvärderingsmätvärden: {result.metrics}")

Detta exempel loggar en OpenAI-modell, förbereder utvärderingsdata och utvärderar sedan modellen med MLflows inbyggda mätvärden för frågesvarsuppgifter.

Anpassade Utvärderingsmätvärden

MLflow tillåter dig att definiera anpassade mätvärden för LLM-utvärdering. Här är ett exempel på att skapa ett anpassat mätvärde för att utvärdera professionalismen i svaren:

from mlflow.metrics.genai import EvaluationExample, make_genai_metric

<p>professionalism = make_genai_metric(
name="professionalism",
definition="Mått på formell och lämplig kommunikationsstil.",
grading_prompt=(
"Ge ett betyg på professionalismen i svaret på en skala från 0-4:\n"
"0: Extremt informell eller olämplig\n"
"1: Informell men respektfull\n"
"2: Måttligt formell\n"
"3: Professionell och lämplig\n"
"4: Mycket formell och expertutformad"
),
examples=[
EvaluationExample(
input="Vad är MLflow?",
output="MLflow är som ditt vänliga grannverktyg för att hantera ML-projekt. Det är supercoolt!",
score=1,
justification="Svaret är informellt och använder informell språk.",
),
EvaluationExample(
input="Vad är MLflow?",
output="MLflow är en öppen källkodsplattform för maskinlärningslivscykeln, inklusive experiment, reproducerbarhet och distribution.",
score=4,
justification="Svaret är formellt, koncist och professionellt utformat.",
)
],
model="openai:/gpt-3.5-turbo-16k",
parameters={"temperature": 0.0},
aggregations=["mean", "variance"],
greater_is_better=True,
)</p>

<p> # Använd det anpassade mätvärdet i utvärdering
result = mlflow.evaluate(
logged_model_info.model_uri,
utvärderingsdata,
targets="grund_sanning",
model_type="frågesvar",
extra_metrics=[professionalism]
)</p>

<p>print(f"Professionalismsscore: {result.metrics['professionalism_mean']}")

Detta anpassade mätvärde använder GPT-3.5-turbo för att bedöma professionalismen i svaren, vilket visar hur du kan utnyttja LLM själva för utvärdering.

Avancerade LLM-utvärderingstekniker

När LLM blir mer avancerade, blir också utvärderingsteknikerna mer avancerade. Låt oss utforska några avancerade utvärderingsmetoder med MLflow.

Retrieval-Augmented Generation (RAG) Utvärdering

RAG-system kombinerar kraften i retrieval-baserade och generativa modeller. Utvärdering av RAG-system kräver bedömning av både retrieval- och genereringskomponenterna. Här är hur du kan konfigurera ett RAG-system och utvärdera det med 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> # Ladda och förbered dokument
loader = WebBaseLoader(["https://mlflow.org/docs/latest/index.html"])
dokument = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texter = text_splitter.split_documents(dokument)</p>

<p> # Skapa vektorlagring
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(texter, embeddings)</p>

<p> # Skapa RAG-kedja
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> # Utvärderingsfunktion
def evaluate_rag(fråga):
result = qa_chain({"query": fråga})
return result["result"], [doc.page_content for doc in result["source_documents"]]</p>

<p> # Förbered utvärderingsdata
utvärderingsfrågor = [
"Vad är MLflow?",
"Hur hanterar MLflow experimentsspårning?",
"Vilka är de viktigaste komponenterna i MLflow?",
]</p>

<p> # Utvärdera med MLflow
with mlflow.start_run():
for fråga in utvärderingsfrågor:
svar, källor = evaluate_rag(fråga)</p>

<p> mlflow.log_param(f"fråga", fråga)
mlflow.log_metric("antal_källor", len(källor))
mlflow.log_text(svar, f"svar_{fråga}.txt")</p>

<p> for i, källa in enumerate(källor):
mlflow.log_text(källa, f"källa_{fråga}_{i}.txt")</p>

<p> # Logga anpassade mätvärden
mlflow.log_metric("genomsnittligt_antal_källor_per_fråga", sum(len(evaluate_rag(q)[1]) for q in utvärderingsfrågor) / len(utvärderingsfrågor))

Detta exempel konfigurerar ett RAG-system med LangChain och Chroma, och utvärderar det genom att logga frågor, svar, hämtade källor och anpassade mätvärden till MLflow.

Chunkningstrategiutvärdering

Sättet du chunkar dina dokument kan ha en betydande inverkan på RAG-prestanda. MLflow kan hjälpa dig att utvärdera olika chunkningstrategier:

import mlflow
from langchain.text_splitter import CharacterTextSplitter, TokenTextSplitter

<p>def evaluate_chunking_strategy(dokument, chunk_size, chunk_overlap, splitter_class):
splitter = splitter_class(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
chunks = splitter.split_documents(dokument)</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("antal_chunks", len(chunks))
mlflow.log_metric("genomsnittlig_chunk_längd", sum(len(chunk.page_content) for chunk in chunks) / len(chunks))</p>

<p> # Utvärdera hämtningsprestanda (förenklad)
korrekt_hämtning = sum(1 for _ in range(100) if simulate_retrieval(chunks))
mlflow.log_metric("hämtningsnoggrannhet", korrekt_hämtning / 100)</p>

<p> # Utvärdera olika strategier
for chunk_size in [500, 1000, 1500]:
for chunk_overlap in [0, 50, 100]:
for splitter_class in [CharacterTextSplitter, TokenTextSplitter]:
evaluate_chunking_strategy(dokument, chunk_size, chunk_overlap, splitter_class)</p>

<p> # Jämför resultaten
bästa_körning = mlflow.search_runs(order_by=["metrics.hämtningsnoggrannhet DESC"]).iloc[0]
print(f"Bästa chunkningstrategi: {bästa_körning['params.splitter_class']} med storlek {bästa_körning['params.chunk_size']} och överlapp {bästa_körning['params.chunk_overlap']}")

Detta skript utvärderar olika kombinationer av chunk-storlekar, överlapp och delningsmetoder, och loggar resultaten till MLflow för enkel jämförelse.

Visualisera LLM-utvärderingsresultat

MLflow erbjuder olika sätt att visualisera dina LLM-utvärderingsresultat. Här är några tekniker:

Använda MLflow UI

Efter att du har kört dina utvärderingar kan du använda MLflow UI för att visualisera resultaten:

  1. Starta MLflow UI: mlflow ui
  2. Öppna en webbläsare och navigera till http://localhost:5000
  3. Välj ditt experiment och körningar för att visa mätvärden, parametrar och artefakter

Anpassade Visualiseringar

Du kan skapa anpassade visualiseringar av dina utvärderingsresultat med bibliotek som Matplotlib eller Plotly, och sedan logga dem som artefakter:

import matplotlib.pyplot as plt
import mlflow

<p>def plot_metric_comparison(mätvärdesnamn, körningsid):
plt.figure(figsize=(10, 6))
for körningsid in körningsid:
körning = mlflow.get_run(körningsid)
mätvärdesvärden = mlflow.get_metric_history(körningsid, mätvärdesnamn)
plt.plot([m.step for m in mätvärdesvärden], [m.value for m in mätvärdesvärden], label=körning.data.tags.get("mlflow.runName", körningsid))</p>

<p> plt.title(f"Jämförelse av {mätvärdesnamn}")
plt.xlabel("Steg")
plt.ylabel(mätvärdesnamn)
plt.legend()</p>

<p> # Spara och logga plotten
plt.savefig(f"{mätvärdesnamn}_jämförelse.png")
mlflow.log_artifact(f"{mätvärdesnamn}_jämförelse.png")</p>

<p> # Användning
with mlflow.start_run():
plot_metric_comparison("svars_relevans", ["körningsid_1", "körningsid_2", "körningsid_3"])

Denna funktion skapar en linjegraf som jämför ett specifikt mätvärde över flera körningar och loggar den som en artefakt.

div]:bg-bg-300 [&_pre]:-mr-4 md:[&_pre]:-mr-9″>

Alternativ till Öppen Källkods-MLflow

Det finns många alternativ till öppen källkods-MLflow för att hantera maskinlärningsarbetsflöden, var och en med unika funktioner och integrationer.

Hanterad MLflow av Databricks

Hanterad MLflow, som värd av Databricks, erbjuder kärnfunktionerna i öppen källkods-MLflow men med ytterligare fördelar som smidig integration med Databricks ekosystem, avancerade säkerhetsfunktioner och hanterad infrastruktur. Detta gör det till ett utmärkt val för organisationer som behöver robust säkerhet och skalbarhet.

Azure Machine Learning

Azure Machine Learning erbjuder en komplett maskinlärningslösning på Microsofts Azure-molnplattform. Det erbjuder kompatibilitet med MLflow-komponenter som modellregistret och experimentsspåraren, även om det inte är baserat på MLflow.

Dedikerade ML-plattformar

Flera företag erbjuder hanterade ML-produkter med olika funktioner:

  • neptune.ai: Fokuserar på experimentsspårning och modellhantering.
  • Weights & Biases: Erbjuder omfattande experimentsspårning, datamängdsversionering och samarbetsverktyg.
  • Comet ML: Tillhandahåller experimentsspårning, modellproduktionsövervakning och dataloggning.
  • Valohai: Specialiserar sig på maskinlärningspipeliner och orkestrering.

Metaflow

Metaflow, utvecklat av Netflix (NFLX ), är ett öppen källkods-ramverk designat för att orkestrera dataarbetsflöden och ML-pipeliner. Även om det excellerar i att hantera stora distributionsprojekt, saknar det omfattande experimentsspårnings- och modellhanteringsfunktioner jämfört med MLflow.

Amazon SageMaker och Google’s Vertex AI

Både Amazon SageMaker (AMZN ) och Google’s Vertex AI erbjuder komplett MLOps-lösningar integrerade i sina respektive molnplattformar. Dessa tjänster erbjuder robusta verktyg för att bygga, träna och distribuera maskinlärningsmodeller i stor skala.

Detaljerad Jämförelse

Hanterad MLflow vs. Öppen Källkods-MLflow

Hanterad MLflow av Databricks erbjuder flera fördelar jämfört med den öppna källkods-versionen, inklusive:

  • Setup och Distribution: Smidig integration med Databricks minskar setup-tiden och ansträngningen.
  • Skalbarhet: Kan hantera stora maskinlärningsarbetsbelastningar med lätthet.
  • Säkerhet och Hantering: Ut-ur-lådan-säkerhetsfunktioner som rollbaserad åtkomstkontroll (RBAC) och datakryptering.
  • Integration: Djup integration med Databricks tjänster, förbättrar interoperabilitet och funktionalitet.
  • Data Lagring och Säkerhetskopiering: Automatiserade säkerhetskopieringsstrategier säkerställer datasäkerhet och tillförlitlighet.
  • Kostnad: Användare betalar för plattformen, lagringen och beräkningsresurserna.
  • Support och Underhåll: Dedikerad support och underhåll tillhandahålls av Databricks.

Slutsats

Spåra Stora Språkmodeller med MLflow ger en robust ram för att hantera komplexiteten i LLM-utveckling, utvärdering och distribution. Genom att följa bästa praxis och utnyttja avancerade funktioner som beskrivs i den här guiden, kan du skapa mer organiserade, reproducerbara och insiktsfulla LLM-experiment.

Kom ihåg att området för LLM utvecklas snabbt, och nya tekniker för utvärdering och spårning dyker upp ständigt. Håll dig uppdaterad med de senaste MLflow-utgåvorna och LLM-forskningen för att kontinuerligt förbättra dina spårnings- och utvärderingsprocesser.

När du tillämpar dessa tekniker i dina projekt, kommer du att utveckla en djupare förståelse för dina LLM:s beteende och prestanda, vilket leder till mer effektiva och tillförlitliga språkmodeller.

Jag har tillbringat de senaste fem åren med att dyka djupt in i den fascinerande världen av Maskinlärning och Djupinlärning. Min passion och expertis har lett mig till att bidra till över 50 olika mjukvaruprojekt, med särskild fokus på AI/ML. Min pågående nyfikenhet har också lett mig mot Naturlig Språkbehandling, ett område som jag är angelägen om att utforska vidare.