Compare commits

...

10 Commits

Author SHA1 Message Date
Yuge Zhang a1386365fa update comment 2025-09-07 09:10:24 +08:00
Yuge Zhang b25d695559 add filter logic 2025-09-07 01:12:51 +08:00
Yuge Zhang f6c2d19deb minor fix 2025-09-07 00:14:04 +08:00
Yuge Zhang d968961b56 debug training 2025-09-07 00:10:28 +08:00
Yuge Zhang 41cf40c439 data conversion 2025-09-06 22:57:55 +08:00
Yuge Zhang a6be4f0a39 capital use case 2025-09-06 22:15:57 +08:00
Yuge Zhang 3f1a333636 logger improve 2025-09-06 15:19:26 +08:00
Yuge Zhang cbb44494d5 cloud finetune dev server 2025-09-06 13:47:49 +08:00
Yuge Zhang bf140b1c98 Azure OpenAI finetune script 2025-09-06 13:31:17 +08:00
Yuge Zhang 6e545951a3 Azure Foundry finetune script 2025-09-06 12:53:47 +08:00
11 changed files with 1729 additions and 0 deletions
+537
View File
@@ -0,0 +1,537 @@
#!/usr/bin/env python3
"""
azure_finetune_openai.py
End-to-end Fine-Tuning & Deployment on Azure OpenAI (via OpenAI Python SDK + Azure Control Plane)
Docs the script is based on (from your tutorial excerpt):
- Fine-tuning overview and SDK usage (Azure OpenAI in Azure AI Foundry Models)
- LoRA-based fine-tuning, JSONL training format, checkpoints, results.csv
- Control plane deployment (PUT to Azure Management API using 2024-10-01)
What this script does:
1) Validates dependencies & environment (AZURE_OPENAI_API_KEY + resource base_url)
2) Creates an OpenAI client pointing at your Azure OpenAI resource
3) Uploads train/validation JSONL files (UTF-8 with BOM, < 512 MB)
4) Starts a fine-tuning job (with optional seed / hyperparameters / suffix)
5) Polls job status to completion (prints events along the way if requested)
6) Lists checkpoints and (optionally) downloads results.csv
7) Deploys the fine-tuned model via Azure CONTROL PLANE (management.azure.com)
8) Runs a sample chat completion against the deployed model (data plane)
9) (Optional) Deletes the deployment
Usage examples:
# Minimal (uses environment AZURE_OPENAI_API_KEY and base_url):
python azure_finetune_openai.py \
--resource-base-url "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/" \
--train-path ./training_set.jsonl \
--val-path ./validation_set.jsonl
# Specify model, seed, and a suffix to tag your FT model:
python azure_finetune_openai.py \
--resource-base-url "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/" \
--model "gpt-4.1-2025-04-14" \
--seed 105 \
--suffix "trialA" \
--train-path ./training_set.jsonl \
--val-path ./validation_set.jsonl
# Deploy with control plane and test inference:
python azure_finetune_openai.py \
--resource-base-url "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/" \
--train-path ./training_set.jsonl \
--val-path ./validation_set.jsonl \
--do-deploy \
--subscription-id "<SUBSCRIPTION_ID>" \
--resource-group "<RESOURCE_GROUP_NAME>" \
--resource-name "<YOUR_AZURE_OPENAI_RESOURCE_NAME>" \
--deployment-name "gpt41-ft-demo" \
--test-prompt "Tell me a haiku about fine-tuning."
# Continue training from a previously fine-tuned model:
python azure_finetune_openai.py \
--resource-base-url "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/" \
--model "gpt-4.1-2025-04-14.ft-5fd1918ee65d4cd38a5dcf6835066ed7" \
--train-path ./training_set_v2.jsonl \
--val-path ./validation_set_v2.jsonl
Notes:
- Ensure your JSONL uses the Chat Completions conversational format.
- You need at least 10 training examples; hundreds+ recommended.
- Fine-tuning access requires the appropriate Azure role (e.g., Cognitive Services OpenAI Contributor).
- Deployment uses the Azure CONTROL PLANE (ARM) and requires an access token:
- Provide via --token, or
- Have Azure CLI installed and logged in; script will attempt to call:
az account get-access-token --resource https://management.azure.com
"""
import argparse
import json
import os
import sys
import time
import subprocess
from typing import Optional, Dict, Any
# OpenAI Python SDK (1.x)
try:
from openai import OpenAI
except Exception as ex:
print("[setup] Missing dependency: openai (pip install openai)")
raise
import requests
# ---------- Helpers ----------
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def require_file(path: str, label: str):
if not os.path.isfile(path):
raise FileNotFoundError(f"{label} not found at: {path}")
size = os.path.getsize(path)
if size >= 512 * 1024 * 1024:
raise ValueError(f"{label} must be < 512 MB; got {size} bytes")
return path
def get_openai_client(resource_base_url: str, api_key: Optional[str]) -> OpenAI:
"""
Create an OpenAI client pointed to the Azure OpenAI *data plane* for your resource.
base_url example: https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/
"""
if not resource_base_url:
raise ValueError("--resource-base-url is required (your Azure OpenAI data-plane endpoint with /openai/v1/)")
if not api_key:
raise ValueError("AZURE_OPENAI_API_KEY must be set in env or passed via --api-key")
client = OpenAI(
api_key=api_key,
base_url=resource_base_url,
)
return client
def upload_files(client: OpenAI, train_path: str, val_path: Optional[str]):
"""
Upload training and validation files. Returns (train_file_id, val_file_id or None)
"""
print("[files] Uploading training file...")
training_response = client.files.create(file=open(train_path, "rb"), purpose="fine-tune")
train_id = training_response.id
print(f"[files] Training file ID: {train_id}")
val_id = None
if val_path:
print("[files] Uploading validation file...")
validation_response = client.files.create(file=open(val_path, "rb"), purpose="fine-tune")
val_id = validation_response.id
print(f"[files] Validation file ID: {val_id}")
print("[files] waiting 10 seconds for files to be processed...")
time.sleep(10) # give the service a moment to process the files
return train_id, val_id
def create_finetune_job(
client: OpenAI,
model: str,
training_file_id: str,
validation_file_id: Optional[str],
seed: Optional[int],
hyperparams: Optional[Dict[str, Any]],
suffix: Optional[str],
) -> str:
"""
Starts a fine-tuning job. Returns the job_id.
"""
payload: Dict[str, Any] = {
"training_file": training_file_id,
"model": model,
}
if validation_file_id:
payload["validation_file"] = validation_file_id
if seed is not None:
payload["seed"] = int(seed)
if hyperparams:
payload["hyperparameters"] = hyperparams
if suffix:
payload["suffix"] = suffix # helps distinguish iterations
print("[ft] Creating fine-tuning job...")
print(f"[ft] Payload: {json.dumps(payload, indent=2)}")
resp = client.fine_tuning.jobs.create(**payload)
job_id = resp.id
print(f"[ft] Job created: {job_id}")
return job_id
def poll_job(client: OpenAI, job_id: str, show_events: bool = False, interval_sec: int = 15) -> Dict[str, Any]:
"""
Polls until the job reaches a terminal state. Returns the final job object (dict-like).
"""
terminal = {"succeeded", "failed", "cancelled"}
last_status = None
printed_event_ids = set()
while True:
job = client.fine_tuning.jobs.retrieve(job_id)
status = job.status
if status != last_status:
print(f"[ft] Status: {status}")
last_status = status
if show_events:
try:
events = client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=20)
for ev in getattr(events, "data", []):
if ev.id not in printed_event_ids:
printed_event_ids.add(ev.id)
ts = getattr(ev, "created_at", None)
msg = getattr(ev, "message", "")
print(f"[ft][event] {ts}: {msg}")
except Exception as ex:
eprint(f"[ft][event] Could not list events yet: {ex}")
if status in terminal:
print(f"[ft] Job finished with status: {status}")
# Convert to plain dict for consistent downstream handling
return json.loads(job.model_dump_json())
time.sleep(interval_sec)
def list_checkpoints(client: OpenAI, job_id: str):
print("[ft] Listing checkpoints...")
try:
resp = client.fine_tuning.jobs.checkpoints.list(job_id)
obj = json.loads(resp.model_dump_json())
checkpoints = obj.get("data", [])
for i, ck in enumerate(checkpoints, 1):
print(f" [{i}] id={ck.get('id')} created_at={ck.get('created_at')} step={ck.get('step')}")
return checkpoints
except Exception as ex:
eprint(f"[ft] Could not list checkpoints: {ex}")
return []
def maybe_download_results_csv(client: OpenAI, job_final: Dict[str, Any], out_dir: str):
"""
If the job succeeded and a result file is present, download it.
"""
status = job_final.get("status")
if status != "succeeded":
print("[results] Job not successful; skipping results.csv download.")
return None
# The tutorial indicates job.result_files[0] will exist when succeeded
result_files = job_final.get("result_files") or []
if not result_files:
print("[results] No result_files found in job; skipping.")
return None
file_id = result_files[0]
print(f"[results] Downloading results file: {file_id}")
retrieve = client.files.retrieve(file_id)
filename = getattr(retrieve, "filename", None) or "results.csv"
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, filename)
with open(out_path, "wb") as f:
result = client.files.content(file_id).read()
f.write(result)
print(f"[results] Saved to: {out_path}")
return out_path
def get_token_from_cli() -> Optional[str]:
"""
Attempt to fetch an ARM token via Azure CLI.
"""
try:
cmd = [
"az",
"account",
"get-access-token",
"--resource",
"https://management.azure.com",
"--query",
"accessToken",
"-o",
"tsv",
]
token = subprocess.check_output(cmd, text=True).strip()
if token:
print("[auth] Obtained ARM token from Azure CLI.")
return token
except Exception as ex:
eprint(f"[auth] Could not fetch token from Azure CLI: {ex}")
return None
def deploy_control_plane(
token: str,
subscription_id: str,
resource_group: str,
resource_name: str,
model_name: str,
deployment_name: str,
api_version: str = "2024-10-01",
sku_name: str = "standard",
capacity: int = 1,
) -> Dict[str, Any]:
"""
Creates/updates a deployment for the fine-tuned model using Azure CONTROL PLANE.
model_name example: gpt-4.1-2025-04-14.ft-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
"""
if not all([token, subscription_id, resource_group, resource_name, model_name, deployment_name]):
raise ValueError("Missing required parameters for control-plane deployment")
request_url = (
f"https://management.azure.com/subscriptions/{subscription_id}"
f"/resourceGroups/{resource_group}"
f"/providers/Microsoft.CognitiveServices/accounts/{resource_name}"
f"/deployments/{deployment_name}"
)
deploy_headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
deploy_data = {
"sku": {"name": sku_name, "capacity": capacity},
"properties": {
"model": {
"format": "OpenAI",
"name": model_name,
"version": "1",
}
},
}
print(f"[deploy] PUT {request_url}?api-version={api_version}")
r = requests.put(
request_url,
params={"api-version": api_version},
headers=deploy_headers,
data=json.dumps(deploy_data),
timeout=180,
)
try:
payload = r.json()
except Exception:
payload = {"text": r.text}
print(f"[deploy] HTTP {r.status_code} {r.reason}")
print(json.dumps(payload, indent=2))
if r.status_code >= 400:
raise RuntimeError(f"Deployment failed: HTTP {r.status_code}")
return payload
def delete_deployment_control_plane(
token: str,
subscription_id: str,
resource_group: str,
resource_name: str,
deployment_name: str,
api_version: str = "2024-10-01",
):
request_url = (
f"https://management.azure.com/subscriptions/{subscription_id}"
f"/resourceGroups/{resource_group}"
f"/providers/Microsoft.CognitiveServices/accounts/{resource_name}"
f"/deployments/{deployment_name}"
)
headers = {
"Authorization": f"Bearer {token}",
}
print(f"[cleanup] DELETE {request_url}?api-version={api_version}")
r = requests.delete(
request_url,
params={"api-version": api_version},
headers=headers,
timeout=180,
)
print(f"[cleanup] HTTP {r.status_code} {r.reason}")
if r.status_code >= 400:
eprint(f"[cleanup] Delete may have failed: {r.text}")
def run_sample_inference(client: OpenAI, deployment_name: str, user_message: str):
"""
Data-plane inference using OpenAI SDK against Azure OpenAI.
In Azure OpenAI with the OpenAI SDK, pass model=<deployment_name>.
"""
print("[infer] Running sample chat.completions...")
resp = client.chat.completions.create(
model=deployment_name,
messages=[{"role": "user", "content": user_message}],
max_tokens=256,
)
print(json.dumps(json.loads(resp.model_dump_json()), indent=2))
# ---------- Main ----------
def main():
parser = argparse.ArgumentParser(description="Azure OpenAI Fine-Tune & Deploy")
# Data-plane
parser.add_argument(
"--resource-base-url",
type=str,
required=True,
help="Azure OpenAI data-plane base URL (e.g., https://<resource>.openai.azure.com/openai/v1/)",
)
parser.add_argument(
"--api-key",
type=str,
default=os.getenv("AZURE_OPENAI_API_KEY"),
help="Azure OpenAI API key (defaults to env AZURE_OPENAI_API_KEY)",
)
parser.add_argument(
"--model",
type=str,
default="gpt-4.1-2025-04-14",
help="Base model or an existing fine-tuned model id to continue from.",
)
parser.add_argument("--train-path", type=str, required=True, help="Path to training JSONL")
parser.add_argument("--val-path", type=str, default=None, help="Path to validation JSONL (optional)")
parser.add_argument("--seed", type=int, default=None, help="Seed for reproducibility")
parser.add_argument("--suffix", type=str, default=None, help="Up to 18 chars to label the fine-tuned model")
parser.add_argument("--n-epochs", type=int, default=None, help="Optional hyperparameter: n_epochs")
parser.add_argument(
"--learning-rate-multiplier", type=float, default=None, help="Optional hyperparameter: learning_rate_multiplier"
)
parser.add_argument("--batch-size", type=int, default=None, help="Optional hyperparameter: batch_size")
parser.add_argument("--show-events", action="store_true", help="Print fine-tuning events while polling")
parser.add_argument("--download-results", action="store_true", help="Download results.csv on success")
parser.add_argument("--results-dir", type=str, default="./ft_results", help="Where to save results.csv")
# Control-plane deploy
parser.add_argument("--do-deploy", action="store_true", help="Create/Update a deployment via Azure control plane")
parser.add_argument("--subscription-id", type=str, default=None, help="Azure subscription ID")
parser.add_argument("--resource-group", type=str, default=None, help="Azure resource group")
parser.add_argument("--resource-name", type=str, default=None, help="Azure OpenAI resource name")
parser.add_argument(
"--deployment-name", type=str, default="gpt41-ft", help="Deployment name to create or update in Azure OpenAI"
)
parser.add_argument(
"--token",
type=str,
default=os.getenv("TOKEN"),
help="ARM bearer token for control-plane calls (tries Azure CLI if not provided)",
)
# Inference + cleanup
parser.add_argument("--test-prompt", type=str, default=None, help="Send a test prompt to the deployed model")
parser.add_argument("--delete-deployment", action="store_true", help="Delete deployment at the end")
args = parser.parse_args()
# Validate files
train_path = require_file(args.train_path, "Training file")
val_path = require_file(args.val_path, "Validation file") if args.val_path else None
# Build hyperparameters payload if provided
hyperparams = {}
if args.n_epochs is not None:
hyperparams["n_epochs"] = int(args.n_epochs)
if args.learning_rate_multiplier is not None:
hyperparams["learning_rate_multiplier"] = float(args.learning_rate_multiplier)
if args.batch_size is not None:
hyperparams["batch_size"] = int(args.batch_size)
if not hyperparams:
hyperparams = None # let service choose defaults
# Client
client = get_openai_client(args.resource_base_url, args.api_key)
# Upload
train_id, val_id = upload_files(client, train_path, val_path)
# Create FT job
job_id = create_finetune_job(
client=client,
model=args.model,
training_file_id=train_id,
validation_file_id=val_id,
seed=args.seed,
hyperparams=hyperparams,
suffix=args.suffix,
)
# Poll
job_final = poll_job(client, job_id, show_events=args.show_events, interval_sec=20)
# Print final job object
print("[ft] Final job object:")
print(json.dumps(job_final, indent=2))
# List checkpoints
list_checkpoints(client, job_id)
# Optionally download results.csv
result_csv_path = None
if args.download_results:
result_csv_path = maybe_download_results_csv(client, job_final, args.results_dir)
# Extract fine-tuned model name/id
fine_tuned_model = job_final.get("fine_tuned_model")
if not fine_tuned_model:
print("[ft] No 'fine_tuned_model' in final job object (job may have failed). Exiting.")
if job_final.get("status") != "succeeded":
sys.exit(2)
print(f"[ft] Fine-tuned model: {fine_tuned_model}")
# Control-plane deploy (optional)
if args.do_deploy:
token = args.token or get_token_from_cli()
if not token:
raise RuntimeError("No control-plane token found. Supply --token or login with Azure CLI.")
if not all([args.subscription_id, args.resource_group, args.resource_name, args.deployment_name]):
raise ValueError(
"--subscription-id, --resource-group, --resource-name, and --deployment-name are required with --do-deploy"
)
deploy_control_plane(
token=token,
subscription_id=args.subscription_id,
resource_group=args.resource_group,
resource_name=args.resource_name,
model_name=fine_tuned_model,
deployment_name=args.deployment_name,
)
# Sample inference (data plane) using the deployment name
if args.test_prompt:
try:
run_sample_inference(client, args.deployment_name, args.test_prompt)
except Exception as ex:
eprint(f"[infer] Inference failed: {ex}")
# Optional cleanup
if args.delete_deployment:
delete_deployment_control_plane(
token=token,
subscription_id=args.subscription_id,
resource_group=args.resource_group,
resource_name=args.resource_name,
deployment_name=args.deployment_name,
)
print("[done] All steps complete.")
if __name__ == "__main__":
main()
@@ -0,0 +1,348 @@
#!/usr/bin/env python3
"""
End-to-end Fine-Tuning & Serverless Deployment on Azure ML (Model-as-a-Service)
https://learn.microsoft.com/en-us/azure/ai-foundry/how-to/fine-tune-serverless?tabs=chat-completion&pivots=foundry-portal
https://github.com/Azure/azureml-examples/blob/main/sdk/python/jobs/finetuning/standalone/model-as-a-service/chat-completion/chat_completion_with_model_as_service.ipynb
This script is a runnable version of the notebook walkthrough. It:
1) Installs/validates dependencies
2) Authenticates to Azure using DefaultAzureCredential with Interactive fallback
3) Connects to your Azure ML Workspace (from config or explicit args)
4) Registers training & validation data assets (train.jsonl / validation.jsonl)
5) Creates & submits a fine-tuning job (CHAT_COMPLETION) for the chosen model
6) Polls for job completion and fetches the registered fine-tuned model name
7) Creates a Serverless Endpoint using the fine-tuned model (same workspace)
8) Performs a sample inference call
9) (Optional) Deletes the serverless endpoint
Usage examples:
# Use config (azureml folder) and default model
python azure_finetune_serverless.py --use-config \
--train-path ./train.jsonl --val-path ./validation.jsonl
# Provide workspace args explicitly
python azure_finetune_serverless.py \
--subscription-id "<SUBSCRIPTION_ID>" \
--resource-group "<RESOURCE_GROUP_NAME>" \
--workspace "<WORKSPACE_NAME>" \
--train-path ./train.jsonl --val-path ./validation.jsonl
Notes:
- Make sure train.jsonl and validation.jsonl are present at the given paths.
- For third-party marketplace models, the script attempts a marketplace subscription.
This is skipped/ignored for Microsoft 1P models like the Phi family.
"""
import argparse
import json
import os
import sys
import time
import uuid
import subprocess
from typing import Optional
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential
from azure.ai.ml.constants import AssetTypes
from azure.ai.ml.entities import Data
from azure.ai.ml.finetuning import FineTuningTaskType, create_finetuning_job
from azure.ai.ml.entities import MarketplaceSubscription, ServerlessEndpoint
def get_credential():
"""
Try DefaultAzureCredential, fall back to InteractiveBrowserCredential.
"""
try:
cred = DefaultAzureCredential()
# Check we can get a token
cred.get_token("https://management.azure.com/.default")
print("[auth] Using DefaultAzureCredential")
return cred
except Exception as ex:
print(f"[auth] DefaultAzureCredential failed: {ex}")
print("[auth] Falling back to InteractiveBrowserCredential...")
return InteractiveBrowserCredential()
def get_workspace_ml_client(
cred, use_config: bool, subscription_id: Optional[str], resource_group: Optional[str], workspace: Optional[str]
) -> MLClient:
"""
Create an MLClient either from local config or explicit parameters.
"""
if use_config:
print("[aml] Connecting from local config...")
try:
return MLClient.from_config(credential=cred)
except Exception as ex:
print(f"[aml] MLClient.from_config failed: {ex}")
print("[aml] Provide explicit --subscription-id, --resource-group, --workspace")
raise
else:
if not all([subscription_id, resource_group, workspace]):
raise ValueError(
"When not using --use-config, you must provide --subscription-id, --resource-group, and --workspace"
)
print(f"[aml] Connecting to workspace: sub={subscription_id} rg={resource_group} ws={workspace}")
return MLClient(
cred, subscription_id=subscription_id, resource_group_name=resource_group, workspace_name=workspace
)
def get_or_create_uri_file_asset(ml_client: MLClient, local_path: str, name: str, version: str) -> Data:
"""
Get or create a URI_FILE data asset pointing to local_path.
"""
try:
asset = ml_client.data.get(name, version=version)
print(f"[data] Dataset '{name}:{version}' already exists.")
return asset
except Exception:
print(f"[data] Creating dataset '{name}:{version}' from path: {local_path}")
data = Data(
path=local_path,
type=AssetTypes.URI_FILE,
description=f"Dataset for {name}",
name=name,
version=version,
)
return ml_client.data.create_or_update(data)
def submit_and_wait_finetune_job(
ml_client: MLClient,
model_id: str,
train_data_id: str,
val_data_id: Optional[str],
model_name_prefix: str,
job_display_name: str,
job_name: str,
experiment_name: str,
):
"""
Create a fine-tuning job and poll until it reaches a terminal state.
"""
print("[ft] Creating fine-tuning job...")
finetuning_job = create_finetuning_job(
task=FineTuningTaskType.CHAT_COMPLETION,
training_data=train_data_id,
validation_data=val_data_id,
hyperparameters={
"per_device_train_batch_size": "1",
"learning_rate": "0.00002",
"num_train_epochs": "1",
},
model=model_id,
display_name=job_display_name,
name=job_name,
experiment_name=experiment_name,
tags={"example": "maas-ft"},
properties={"created_by": "azure_finetune_serverless.py"},
output_model_name_prefix=model_name_prefix,
)
created_job = ml_client.jobs.create_or_update(finetuning_job)
print(f"[ft] Submitted job: {created_job.name} | status={created_job.status}")
# Poll for completion
terminal = {"Completed", "Failed", "Canceled"}
while True:
job = ml_client.jobs.get(created_job.name)
print(f"[ft] Current job status: {job.status}")
if job.status in terminal:
print(f"[ft] Job finished with status: {job.status}")
return job
time.sleep(30)
def maybe_create_marketplace_subscription(ml_client: MLClient, base_model_id: str, normalized_model_name: str):
"""
Attempt a marketplace subscription for third-party models.
Skip for Microsoft 1P models (e.g., Phi family).
If not required or already exists, this will be ignored.
"""
try:
model_id_to_subscribe = "/".join(base_model_id.split("/")[:-2])
subscription_name = f"{normalized_model_name}-sub"
ms = MarketplaceSubscription(model_id=model_id_to_subscribe, name=subscription_name)
print(f"[marketplace] Creating/ensuring subscription: {subscription_name}")
ml_client.marketplace_subscriptions.begin_create_or_update(ms).result()
print("[marketplace] Subscription created/verified.")
except Exception as ex:
print(f"[marketplace] Skipping or already subscribed: {ex}")
def create_serverless_endpoint(ml_client: MLClient, endpoint_name: str, model_id: str):
"""
Create or update a ServerlessEndpoint for the fine-tuned model.
"""
print(f"[endpoint] Creating/Updating serverless endpoint: {endpoint_name}")
se = ServerlessEndpoint(name=endpoint_name, model_id=model_id)
ml_client.serverless_endpoints.begin_create_or_update(se).result()
print("[endpoint] Endpoint is ready.")
def run_sample_inference(ml_client: MLClient, endpoint_name: str, user_message: str):
"""
Run a basic chat-completions request against the serverless endpoint.
"""
from urllib.parse import urljoin
import requests
endpoint = ml_client.serverless_endpoints.get(endpoint_name)
keys = ml_client.serverless_endpoints.get_keys(endpoint_name)
auth_key = keys.primary_key
url = f"{endpoint.scoring_uri}/v1/chat/completions"
payload = {
"max_tokens": 256,
"messages": [{"role": "user", "content": user_message}],
}
headers = {"Content-Type": "application/json", "Authorization": f"{auth_key}"}
print(f"[infer] POST {url}")
r = requests.post(url, json=payload, headers=headers, timeout=120)
r.raise_for_status()
print("[infer] Response JSON:")
print(json.dumps(r.json(), indent=2))
def maybe_delete_endpoint(ml_client: MLClient, endpoint_name: str, do_delete: bool):
if do_delete:
print(f"[cleanup] Deleting endpoint: {endpoint_name}")
ml_client.serverless_endpoints.begin_delete(endpoint_name).result()
print("[cleanup] Endpoint deleted.")
def main():
parser = argparse.ArgumentParser(description="Azure ML Fine-tune & Serverless Deploy (MaaS)")
parser.add_argument("--use-config", action="store_true", help="Use MLClient.from_config (azureml config)")
parser.add_argument("--subscription-id", type=str, default=None, help="Azure subscription ID")
parser.add_argument("--resource-group", type=str, default=None, help="Azure resource group")
parser.add_argument("--workspace", type=str, default=None, help="Azure ML workspace name")
parser.add_argument(
"--model-name",
type=str,
default="Phi-4-mini-instruct",
help="Base model name in system registry (e.g., Phi-4-mini-instruct)",
)
parser.add_argument("--train-path", type=str, required=True, help="Path to train.jsonl")
parser.add_argument("--val-path", type=str, required=True, help="Path to validation.jsonl")
parser.add_argument(
"--endpoint-name",
type=str,
default=None,
help="Optional serverless endpoint name (must be unique in workspace)",
)
parser.add_argument("--skip-infer", action="store_true", help="Skip the sample inference call")
parser.add_argument("--delete-endpoint", action="store_true", help="Delete the endpoint at the end")
args = parser.parse_args()
# Auth
cred = get_credential()
# Workspace client
ml_client = get_workspace_ml_client(
cred,
use_config=args.use_config,
subscription_id=args.subscription_id,
resource_group=args.resource_group,
workspace=args.workspace,
)
# Also need a registry client for system registry "azureml"
registry_ml_client = MLClient(cred, registry_name="azureml")
# Workspace details
workspace = ml_client._workspaces.get(ml_client.workspace_name)
print(f"[aml] Workspace: name={ml_client.workspace_name} location={workspace.location}")
# Try both attributes for workspace ID (SDK versions differ)
ws_guid = getattr(workspace, "_workspace_id", None)
if not ws_guid:
# For newer SDKs, workspace.id is full ARM ID; we only need the workspace name for AzureML URI.
# However, azureml:// URIs typically use the GUID. We attempt to parse if possible.
# If not available, fall back to the name (works in many cases).
ws_guid = getattr(workspace, "workspace_id", None) or ml_client.workspace_name
# Pick a model to fine-tune
model_name = args.model_name
try:
model_to_finetune = registry_ml_client.models.get(model_name, label="latest")
except Exception as ex:
print(f"[model] Failed to get model: {model_name}")
available_models = [m.name for m in registry_ml_client.models.list()]
print(f"[model] Available models: {available_models}")
raise
print(f"[model] Using: name={model_to_finetune.name} version={model_to_finetune.version}")
base_model_id = model_to_finetune.id
normalized_model_name = model_name.replace(".", "-")
# Optionally create marketplace subscription for 3P models (ignored for 1P like Phi family)
maybe_create_marketplace_subscription(ml_client, base_model_id, normalized_model_name)
# Create training/validation data assets
# Use version suffix to avoid collisions
# version_suffix = time.strftime("%Y%m%d%H%M%S")
version_name = "1"
train_asset = get_or_create_uri_file_asset(ml_client, args.train_path, "chat_training_small", version_name)
val_asset = get_or_create_uri_file_asset(ml_client, args.val_path, "chat_validation_small", version_name)
# Create fine-tune job & wait
guid = str(uuid.uuid4())[:8]
display_name = f"{model_name}-display-name-{guid}-from-sdk"
job_name = f"{model_name}-ft-{guid}-from-sdk"
out_prefix = f"{model_name}-{guid}-from-sdk-finetuned"
experiment = f"{model_name}-from-sdk"
job = submit_and_wait_finetune_job(
ml_client=ml_client,
model_id=base_model_id,
train_data_id=train_asset.id,
val_data_id=val_asset.id,
model_name_prefix=out_prefix,
job_display_name=display_name,
job_name=job_name,
experiment_name=experiment,
)
# Fetch registered model name from job outputs
try:
finetune_model_name = job.outputs["registered_model"]["name"]
print(f"[ft] Registered fine-tuned model name: {finetune_model_name}")
except Exception as ex:
print(f"[ft] Could not read registered model name from job outputs: {ex}")
print("[ft] Exiting early.")
sys.exit(2)
# Build AzureML model URI for serverless endpoint
model_id_uri = (
f"azureml://locations/{workspace.location}/workspaces/{ws_guid}/models/{finetune_model_name}/versions/1"
)
print(f"[endpoint] Using model id URI: {model_id_uri}")
# Create endpoint name (must be unique)
endpoint_name = args.endpoint_name or f"{normalized_model_name}-ft-{guid}"
create_serverless_endpoint(ml_client, endpoint_name, model_id_uri)
# Sample inference
if not args.skip_infer:
try:
run_sample_inference(
ml_client,
endpoint_name,
user_message="Summarize the following dialogue in 3 sentences.\nAmanda: I loved the film!\nThierry: Same here, the pacing was perfect.\nAmanda: And the soundtrack? Phenomenal.",
)
except Exception as ex:
print(f"[infer] Inference failed: {ex}")
# Optional cleanup
maybe_delete_endpoint(ml_client, endpoint_name, args.delete_endpoint)
if __name__ == "__main__":
main()
@@ -0,0 +1,79 @@
{"messages":[{"content":"Summarize this dialog:\nDenny: <file_photo>\r\nDenny: sleep tight my dearest!\r\nWilma: Morning! thanks for the photos! may I forward them to the Hobbs?\r\nWilma: it's 9:40! where are you?\r\nDenny: did you forget? I've got an appointment at 10\r\nWilma: sorry!! I forgot\r\nWilma: are you in the waiting room?\r\nDenny: just arrived\r\nDenny: I'll call you afterwards\r\nWilma: ok\n---\nSummary:\n","role":"user"},{"content":"Denny has an appointment at 10. He'll call Wilma afterwards.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMary: Where are u?\r\nMary: I'm freezing here!\r\nAlice: I'm on my way.\r\nAlice: Sorry, I have some problems with my mum.\r\nAlice: She dont't want me to go :\/\r\nMary: Don't be joking!\r\nMary: Why?\r\nAlice: She doesn't trust Jack...\n---\nSummary:\n","role":"user"},{"content":"Mary is cold and waiting for Alice. Alice is on her way. Alice's mom doesn't want Alice to go, as she doesn't trust Jack.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nIsabelle: So, what time will you be there?\r\nRyan: I won\u2019t\r\nIsabelle: What??\r\nRyan: Me and Irma, we\u2019re going to the cinema together\r\nIsabelle: Loool, not cool, both of you promised to come!\r\nRyan: I know, but\u2026 we just want to spend some time together before I go to London\r\nIsabelle: Ooooookay, I can see sth\u2019s going on o.O\r\nRyan: Yea, kind of ;p\r\nIsabelle: Meaning\u2026? ;d\r\nRyan: Were going out a bit, that\u2019s it\r\nIsabelle: Hmmm right, so what am I supposed to tell the others?\r\nRyan: The truth :P\n---\nSummary:\n","role":"user"},{"content":"Ryan and Irma are going to the movies tonight instead of meeting Isabelle as promised. Ryan will be leaving for London soon and wants to spend time with Irma.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nAnita: How are you doing?\r\nRuby: good! yourself?\r\nAnita: good enough I think.\r\nRuby: How is your work going?\r\nAnita: I haven't painted anything for the last year.\r\nRuby: I see, why?\r\nAnita: I just can't work\r\nRuby: I am sorry...\r\nAnita: Maybe it will be possible one day to come back to work.\r\nRuby: I'm sure it will.\r\nAnita: Maybe if we could try again?\r\nRuby: We talked about it so many times, don't you think?\r\nAnita: Sorry...\r\nRuby: Please, take care of yourself and give it some time.\r\nAnita: I shouldn't have written \r\nRuby: it's fine. Don't blame yourself.\r\nAnita: Have a good day\r\nRuby: you too\n---\nSummary:\n","role":"user"},{"content":"Anita hasn't painted anything for a year. She asked Ruby to give them another try, but Ruby refused. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nShelly: How did Max find out there was no Santa?\r\nDiane: He just kind of figured it out when he was about 5 or so.\r\nShelly: I'm having trouble with Taylor. \r\nShelly: Some kid at school told her there was no Santa!\r\nDiane: That was bound to happen. Just tell her that kid has their own opinion and she doesn't have to share it.\r\nShelly: That's a good one. I called the teacher also. Too much?\r\nDiane: Yes. Keep it between you and Taylor and don't make it a big deal.\r\nShelly: You're right. Thanks for the advice!\r\nDiane: NP! I actually miss the Santa days!\r\nShelly: I know, they grow up too fast!\r\nDiane: Not little kids anymore!\r\nShelly: :'\u2011(\r\nDiane: I also miss Elf on the Shelf! Got him to go to bed on time! LOL!\r\nShelly: See, I think that's creepy!\r\nDiane: It is a bit creepy, but does the trick.\r\nShelly: I suppose. Unless they catch you moving the elf. \r\nDiane: Uh oh!\r\nShelly: Yep, only one Christmas in our house and I was busted! LOL!\r\nDiane: LOL!\r\nShelly: Have a good night! See you at the gym!\r\nDiane: You too! See you!\n---\nSummary:\n","role":"user"},{"content":"Diane's son, Max, found out that there is no Santa at the age of 5. Shelly's daughter, Taylor, was told at school that there is no Santa by some kid. Diane suggests not to make a big deal out of it.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMaria: Have you seen my jumper?\nJoseph: A black one?\nAmy: no\nMaria: yes!!\nJoseph: You left it in the office\nMaria: Ufff\nMaria: Thanks Joseph \n---\nSummary:\n","role":"user"},{"content":"Maria left her black jumper in the office.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nTracy: Are you on the bus already?\nBob: Yes, we'll be at the station in about 15min\nDominic: maybe 20\nTracy: great!\n---\nSummary:\n","role":"user"},{"content":"Bob and Dominic are already on the bus. They'll be at the station in about 15-20 minutes.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLena: Hi Gary!\nLena: Are you home now?\nGary: Hello!\nGary: I was (and still am) at home but I wasn't logged in here\nLena: Do you have time to skype?\nLena: I can't sleep.\nGary: Sure, give me 5 minutes.\nLena: Sure.\nGary: Ok.\nGary: I'm ready and \"hidden\" on skype ;)\nLena: Calling.\n---\nSummary:\n","role":"user"},{"content":"Lena cannot sleep and want to talk with Gary on Skype. Gary is at home and is logged as \"hidden\" on Skype. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSynthia: You won\u2019t believe what happened to me!\r\nJoan: Shoot!\r\nSynthia: Oh my gosh, I\u2019m sooo upset\uf04c\r\nJoan: C\u2019mon, what happened??\r\nSynthia: Do you remember my friend, Mike?\r\nJoan: The one from high-school? Yeah, I do. \r\nSynthia: I just run into him at the supermarket.\r\nJoan: And?\r\nSynthia: And he said he just met someone me.\r\nJoan: And????\r\nSynthia: I don\u2019t know, this guy\u2019s been always driving me crazy.\r\nJoan: So, who did he see? What\u2019s the problem?\r\nSynthia: I don\u2019t\u2019 know, I didn\u2019t even ask, but why is he even talking to me? I don\u2019t even like him.:-\/\r\nJoan: Well, maybe he just remembers you.\r\nSynthia: So what?\r\nJoan: So, maybe he just wanted to say hi \uf04a\r\nSynthia: I don\u2019t care. I don\u2019t like this dude. I wish I wouldn\u2019t see him at all.\r\nJoan: OK, so next time just tell him you\u2019re busy and it was great to see him.\r\nSynthia: Well, I think I\u2019ll just walk away the other direction. \r\nJoan: Fine, whatever works. Gotta go. \r\nSynthia: Bye. \n---\nSummary:\n","role":"user"},{"content":"Synthia met her friend Mike and she is very upset about it. Joan suggests to just say hi next time. Synthia decides to just ignore him.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJeff: how are we going to the party?\r\nJospeh: should we take a tram?\r\nJeff: we can also walk\r\nMelissa: no, it's too cold and too far\r\nBarbara: where does she live actually?\r\nMelissa: I think somewhere in Novoli\r\nBarbara: ok, I won't walk to Novoli for sure\r\nJeff: we could take car2go\r\nMelissa: if there is any in the area\r\nJeff: because Uber won't work tonight I suppose\r\nMelissa: no way, New Year's Eve is always a disaster when it comes to taxis\r\nBarbara: let's try car2go\r\nJeff: and if it doesn't work, we will take a tram\r\nBarbara: exactly\n---\nSummary:\n","role":"user"},{"content":"Jeff, Jospeh, Melissa and Barbara are going to the party in Novoli. It's too cold for a walk and the taxies are unavaliable on New Year's Eve. They decide to try car2go. The worst case scenario they will take a tram.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSophia: Hi Lina, my daughter Parvati is interested in cooking classes. you still have room?\r\nLina: of course, no problem, next session is saturday the 10th\r\nSophia: thanks could you tell me how does it cost? \r\nLina: 20 euros each class. you may pay by cash or transfer\r\nSophia: great, Parvati is so happy.\n---\nSummary:\n","role":"user"},{"content":"Parvati will attend Lina's cooking class. The next session is on the 10th. Each session costs 20 euros, payable by cash or transfer.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nTim: We are raising funds for children in need! Come along and bring your friends and family! I hope to see you there! \r\nDonna: Do you need volunteers?\r\nTim: Volunteers much needed! \r\nDonna: i\u2019d be more than happy to help! X\r\nRose: count on me too!\r\nKevin: that is awesome mate what you\u2019re doing!\r\nGreg: Go go go mate!\r\nEmma: shared\r\nGreg: I am ready to help out too! \n---\nSummary:\n","role":"user"},{"content":"Tim is raising funds for children in need. Donna, Greg and Rose want to help out as volunteers.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBill: can you pick up my package from the post office on the way home?\r\nStacy: is it something heavy? :)\r\nBill: no, it's a new battery for my cellphone\r\nStacy: sure thing then honey :*\r\nBill: thanks baby :*\n---\nSummary:\n","role":"user"},{"content":"Stacy will pick up a battery from the post office on Bill's request.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nKadisha: Hellooo!! You here??\nKadisha: I sent you a video clip on fb\nKadisha: <file_video> \nWaldemar: WTF?? LOL!!\nWaldemar: Hilarious shit!!!\nWaldemar: And there's a whole collection \ud83e\udd23\ud83e\udd23\ud83e\udd23\nWaldemar: Have you seen the rest?\nWaldemar: Hahahaha\nKadisha: Is there??\nKadisha: No I haven't \ud83d\ude1c\nKadisha: I'll check it out..\nKadisha: Same characters?\nWaldemar: Yeah gremlins and shit \ud83e\udd23\nWaldemar: Check this one out\nWaldemar: <file_video> \nKadisha: loool \ud83d\ude04\ud83d\ude04\ud83d\ude04\nKadisha: That's totally screwed\n---\nSummary:\n","role":"user"},{"content":"Kadisha and Waldemar share funny videos.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBrian: Hello everyone! What has been your favourite moment of the ceremony so far?\r\nStorm: Just joined. I'm enjoying the speech by President Marcon. I pray ppl in my country are listening. I hope our current ruler is listening. We are on very thin ice over here in the US. I don't think ppl truly understand the value of the past.\r\nPatte: Macron's speech (and I am not a particular fan of his)\r\nLaura: Brian the musical performances.\r\nDenis: The view from the Arc down the Champs. Seeing the lettering on the monument, and the students reading the letters of soldiers.\r\nAngie: Brian when he said nationalism was the opposite of patriotism. So true and I wish others would realize it.\r\nAnne: \"Nationalism is the betrayal of patriotism \" Macron, 11\/11\/2018 Love it!\r\nMargaret: My daughter went to a local fair in Sydney today and all the hundreds attending fell silent at 11am. Very moving!\r\nDenis: Its a Beautiful moment in the history of the world\r\nJan: Unfortunate that when a letter by Remarque was being read in German, both CNN and BBC reporters starting talking about something else.\r\nLaura: I am so sorry for every Country's loss of friends, family, neighbors and Citizens. So many attending are emotional. My heart and prayers go out to all of them.\ud83d\ude2a\r\nTom: in fact African leaders shouldn't have been invited because they have failed Africa and the world as a whole\r\nPatte: Tom you don't understand the global capital. Europe is a partner to the demise of Africa. African leaders have colluded with global capital. go read up on Togo politics.\r\nDestiny: There's no single benefit after war, Sincere peace is the ultimate. Therefore I urge the whole world to embrace peace.\r\nAngie: Agree!\r\nLarry: War is what comes when people give up on peaceful solutions . Ideas are what keep us from war. Love and Trust are always better than Fear and Doubt.\r\nLarry: Today is Veterans Day in the US. We honor everyone\u2019s service to their respective countries \r\nPeter: What about the killings that are happening right now because of you and your allies, around the world or the middle east to be precise.\r\nKafuka: exactly my thoughts.\r\nLarry: The United States has always tried to be peaceful and honorable. Are we perfect? No! But at least we try. We never asked for 911.\r\nKafuka: Larry, leave Internet. Now.\n---\nSummary:\n","role":"user"},{"content":"What Storm and Patte liked the most about the ceremony was President Marcon's speech. Laura's favourite moment was musical performances. Denis liked the view from the Arc down the Champs. Destiny, Angie and Larry stand for peaceful solutions. Larry and Kafuka are against US military actions. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nNathan: my mum is making trifles tonight\r\nNathan: wanna come over?\r\nSue: that sounds DELICIOUS!!\r\nSue: and your mom is your an amazing cook :-D\r\nNathan: they're strawberry and almond trifles\r\nSue: WOW\r\nSue: what time should i be there?\r\nNathan: 7\r\nSue: i'll be there at 7\r\nSue: and i'll bring a bottle of wine\r\nNathan: Thanks!!!\n---\nSummary:\n","role":"user"},{"content":"Sue will come to Nathan at 7 because his mum is making trifles tonight. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMary: Hello. Im writing to let you know the cake you ordered is ready. Feel free to come and get it whenever you want.\r\nFred: Thank you really much! I'm afraid though I won't be able to get it before friday. That a problem?\r\nMary: Not at all. However, bear in mind we're only open till midday on Fridays. \r\nFred: Doesn't sound good. What about Saturday? Are you open??\r\nMary: Absolutely. Also here till midday.\r\nFred: great. So see you on Saturday.\n---\nSummary:\n","role":"user"},{"content":"Fred's cake is ready. He cannot pick it up on Friday so he will do it on Saturday. The place is open until midday on Friday and Saturday.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nPatty: Lunch, anyone? \r\nFred: Yesss please!\r\nBecky: Totally, I'm starving!\r\nPatty: 1pm in the lobby\r\nBecky: I'm in\n---\nSummary:\n","role":"user"},{"content":"Patty, Fred and Becky are meeting at 1 pm in the lobby.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nOmar: do you need any work done this week?\r\nJenny: yes I could do with a hand in the kennels\r\nOmar: great I'll come over in a hour or so then, do you need anything?\r\nJenny: Yes bring your toolbox I need that sink pipe undoing \r\nOmar: ok see you soon\n---\nSummary:\n","role":"user"},{"content":"Omar will come over in an hour to help with the kennels. Jenny wants Omar to bring his toolbox. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nTina: Gals,would it be ok if we met at 6 PM instead of 5 on Friday? My hairdresser just offered that I can come at 4 on Friday - his previous visit got cancelled or something - and I'm not sure if I can make it on time in this case.\r\nLucy: no problem\r\nMarge: it's even better for me\r\nTina: thanks a lot ;*\r\nLucy: so you finally got that appointment, huh? ;)\r\nTina: yeah, you know how long I've been waiting for it? Jeez\r\nMarge: no wonder, they have great reviews everywhere\r\nTina: exactly, I can't wait ^^\r\nLucy: congrats ;)\r\nTina: thx :*\n---\nSummary:\n","role":"user"},{"content":"Tina, Lucy and Marge will meet at 6 PM instead of 5 PM on Friday as there's a possibility for Tina to go to the hairdresser at 4 PM. Tina has been waiting a long time for the appointment. The hairdresser has good reviews.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJules: Hi there!\r\nAnna: Hey, I meant to contact you yesterday :)\r\nAnna: Any suggestions or preferences? \r\nJules: are you talking about the birthday present?\r\nAnna: Yes :) \r\nJules: elsa accessories would be ok\r\nAnna: great, thanks!\r\nAnna: and how are you doing these days? \r\nJules: we're good thanks\r\nJules: i've changed my working hours and now I only work 7hrs\r\nAnna: super!\r\nJules: I can pick her up earlier and she isn't so tired\r\nAnna: sure\r\nJules: And how are you doing?\r\nAnna: good, thanks\r\nAnna: I'm busy studying for the exam \r\nAnna: it's on Friday\r\nJules: So soon?\r\nAnna: Yeah\r\nJules: Ok, I don't want to distract you from studying ;) \r\nJules: Good luck and be in touch, girl!\r\nAnna: Thanks, speak to you soon\n---\nSummary:\n","role":"user"},{"content":"According to Jules, Elsa accesories will make a good present. She works less now. Anna is preparing for the Friday's exam.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMichael: Hey honey, would you mind taking our dog to the vet today?\r\nMichael: something came up and I can't make it\r\nTherese: Oh yeah, no problem :)\r\nMichael: You're the best!\n---\nSummary:\n","role":"user"},{"content":"Therese will take the dog to the vet, as Micheal can't make it.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSheridan: Did you see that pink fridge?\r\nElias: Yes. Vomit!\r\nSheridan: What WAS she THINKING???\r\nElias: She wasn't!\r\nSheridan: Fashion victim!\r\nElias: A fridge isn't fashion!\r\nSheridan: Don't care. It's still horrid.\r\nElias: I'm not sure pink and gray are the in thing, you know?\r\nSheridan: Remember when it was in in the 80s?\r\nElias: Uh, how can I forget?\r\nSheridan: Gray is in but with pastels? Vom!\r\nElias: <file_photo>\r\nSheridan: ARE YOU KIDDING????\r\nElias: LOL!\r\nSheridan: My eyes! My eyes!\r\nElias: Some people like it!\r\nSheridan: Not this people! LOL!\r\nElias: Yeah, I got that!\r\nSheridan: Anyway, can't unsee that.\r\nElias: LOL! Brain bleach!\n---\nSummary:\n","role":"user"},{"content":"Sheridan and Elias are criticising her pink fridge. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nGrey: if i had to guess, its you who started the fight\r\nYuri: hey what do you mean -_- who's side are you on\r\nGrey: hey im on your side, if they want a fight we'll give them one\r\nYuri: yeah\r\nGrey: but seriously, who started it xD\r\nYuri: it wasn't me this time\r\nGrey: thank God!\n---\nSummary:\n","role":"user"},{"content":"This time Yuri didn't start the fight. Grey has got Yuri's back.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSylvia: Chris asked me ou!\nRebecca: OMG!\nDave: Whoooooah!!! You go girl!\nSylvia: I know! I\u2019m so hyped!!!\nRebecca: Tell us more! When, where? :D\nSylvia: We\u2019re meeting at 8, but I don\u2019t know where we\u2019re going\nSylvia: He said it will be a surprise <3\nDave: Oh my, so romantic <3\nRebecca: What are you going to wear?\nSylvia: I don\u2019t know, I don\u2019t know where we\u2019re going\u2026\nRebecca: Hm, go with something simple\nDave: But a dress, you need to wear a dress!\n---\nSummary:\n","role":"user"},{"content":"Chris asked Sylvia out. They are meeting at 8.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nCarolyn: I\u2019m so hype! Look, aren\u2019t they gorgeous?\r\nCarolyn: <file_photo>\r\nAnn: Dope shoes! Where did you buy them?\r\nCarolyn: on the internet \ud83d\ude0a\r\nMary: Cool!\n---\nSummary:\n","role":"user"},{"content":"Carolyn bought fantastic shoes on the internet. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nVanessa: Hey, I'm thinking of buying a new phone and I was wondering whether you could give me some advice on that.\r\nLindsey: Hi, Vanessa. Personally I'm a fan o Samsung galaxy series. The model depends on your budget for this.\r\nHarry: I'm not a fan of android so I'd recommend an iphone - I've been using one for years it's great.\r\nVanessa: Yeah, I'm a bit on budget - but not so much I can only afford the cheapest models. Any particular not terribly expensive models you both would like to recommend?\r\nLindsey: The s-series is no longer the latest one so e.g. galaxy s6 or s7 would be cheaper now. They're a couple of years old but work perfectly fine as far as I know\r\nHarry: the budget version would be iphone 6\r\nVanessa: Thanks a lot for the advice guys. I'll look into those models.\r\nHarry: any time\n---\nSummary:\n","role":"user"},{"content":"Vanessa plans to buy a new phone and needs advice on a reasonably priced model. Lindsey recommends Galaxy s6 or s7 while Harry suggests iPhone 6.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nAbigail: Jacob, I need to ask you a favor. \r\nJacob: Yeah, sure, what's up.\r\nAbigail: I need help deciding which haircut I should get. \r\nJacob: Ha, wouldn't it be better if you asked Lily or Heather for that?\r\nAbigail: No no, I need a man's opinion for this one. \r\nAbigail: Lily and Heather were useless.\r\nJacob:\ud83d\ude05\ud83d\ude05\ud83d\ude05\r\nJacob: Well, I am not sure I will be of greater use, but sure go ahead. \r\nAbigail: Alright, I am just gonna send you a few pics, and just let me know which one you think would look the best on me. \r\nJacob: ok \ud83d\ude05\r\nAbigail: <file_picture>\r\nAbigail: <file_picture>\r\nAbigail: <file_picture>\r\nAbigail: <file_picture>\r\nJacob: Dang, that's a lot of options. I'm a little overwhelmed \ud83d\ude05\r\nJacob: Ok well I think the first one is a no for sure. \r\nJacob: I don't like the color, I don't think it would suit you. \r\nAbigail: Alright, that one wasn't my favorite anyway. \r\nAbigail: What do you think of the last one?\r\nJacob: I mean, it's ok. Nothing special \ud83d\ude05\r\nAbigail: Really?! Well. I think it's nice. \r\nJacob: Haa, so you obviously like that one the best. I don't know why you are asking other people for opinions then. \r\nAbigail: Ah!! You're the worst. \r\nAbigail: hahah but I think you're right. \r\nAbigail: Alright, thanks for the help \r\nJacob: Yeah, no problem \ud83d\ude05\n---\nSummary:\n","role":"user"},{"content":"Abigail needs Jacob's opinion on which haircut she should get. Abigail will go for the last one.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nEnzo: dude you up?\r\nSimon: im surprised your up at this hour\r\nEnzo: yeah im not feeling well\r\nSimon: hey whats up\r\nEnzo: asthma attacks\r\nSimon: shit. how bad is it, let me take you to the medical room\r\nEnzo: its bad, i cant go\r\nSimon: okay let me bring some medicine for you\r\nEnzo: that would be really helpful\r\nSimon: do you have your inhaler\r\nEnzo: no i dont\r\nSimon: ill bring it to you\r\nEnzo: Salbutamol\r\nSimon: Salbutamol, got it!! ill be right back\r\nEnzo: thanks man\r\nSimon: hey no problem\n---\nSummary:\n","role":"user"},{"content":"Enzo is having bad asthma attacks. Simon will bring the Salbutamol inhaler for Enzo.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nGrace: Did you get a damage waiver?\r\nPhil: Nooooo...\r\nGrace: Then you have to pay for all of that!\r\nPhil: Ugh.\n---\nSummary:\n","role":"user"},{"content":"Phil didn't get a damage waiver, so he'll have to pay for all of that.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLib: Thank you for the flowers, they are amazing!\r\nLiz: You are welcome! \r\nLib: So good to see you at the weekend we should stay in touch\r\nLiz: Yes, definitely\r\nLib: and let's hope that next time we meet, it will be a happier occasion\r\nLiz: Yes I am sure it will be!\r\nLib: Let me know next time you are coming to London\r\nLiz: Yes I will\r\nLib: Thank you for the photo too, it means a lot to me\r\nLiz: You are welcome. My dad used to keep it in his study, but when he died I wanted to give it back to your mum.\r\nLib: She would have loved it!\r\nLiz: I still can't believe she's not here...\r\nLib: I know, it's terrible isn't it.\r\nLiz: Yes I miss her so much\r\nLib: Me too!\r\nLiz: She was a great person. I will stay in touch and try to meet up next time I am in London.\r\nLib: Thank you for everything\n---\nSummary:\n","role":"user"},{"content":"Lib came to London. She brought a meaningful photo with her that was in her father's possession before he passed away. She wants to keep in touch with Liz after her departure.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nPam: Have you seen my hairdryer?\r\nPam: I can't find it anywhere.\r\nLisa: Oh, damn, I forgot to tell you...\r\nLisa: It has broken down this morning\r\nLisa: So I called Chris and he told me to bring it to him and he'll cast an eye over it\r\nPam: For fuck's sake!\r\nPam: What am I supposed to do now?! Shit!\r\nLisa: I'm really sorry, but it's nobody's fault\r\nLisa: It's called perversity of inanimate objects, nothing more\r\nPam: Fuckin' bad luck\n---\nSummary:\n","role":"user"},{"content":"Pam's hairdryer broke and Lisa gave it to Chris to fix it.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLiz: yoooo i saw the cutest movie yesterday <3\r\nLiz: dumplin' \r\nCarolina: what?!\r\nLiz: the new netflix film with Jennifer Aniston\r\nCarolina: oh haha i thought you were calling ME dumplin'\r\nLiz: loooool new nickname!\r\nCarolina: X-D don't you dare!!\r\nLiz: :-P\r\nCarolina: so I guess it's good?\r\nLiz: yeah, it was light and sweet, perfect for a lazy night in\r\nLiz: and the soundtrack is all Dolly Parton\r\nCarolina: Jolene, Jolene, Jolene, Joleeeeeeeeeeene\r\nLiz: :-D\r\nCarolina: I'm so watching it tonight\n---\nSummary:\n","role":"user"},{"content":"Liz saw the movie \"Dumplin'\"and recommends it to Carolina. The soundtrack to the movie consists exclusively of Dolly Parton songs. Carolina is going to watch the movie tonight.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nNick: Is the restaurant open already?\r\nManager: It is, would you like to book a table?\r\nNick: Yes, please. Table for 2 at 1 pm today.\r\nManager: Certainly, done.\r\nNick: Thank you, see you there.\r\nManager: See you at 1 pm, sir.\n---\nSummary:\n","role":"user"},{"content":"Nick has reserved a table for two at 1 pm today.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nReggie: Hi Rob, you ok, man?\r\nRob: Wow, Reggie! Two messages in 2 months, lot for you!\r\nReggie: Yeah! Anyway, remember we talked about that drink a while ago, well I'm back home his weekend, Dad's 60th on Sunday, big family do, you know. Showing me off to everyone, know what my old man's like!\r\nRob: Yeah, love Reginald! He still at the factory?\r\nReggie: Yeah, hoping to finish there soon. Mum's at school still, she'll never leave!\r\nRob: Yeah, weird your mum teaching us, God it must be about 25 years ago. Mrs Wright's reception class!\r\nReggie: My God, yes, it was even weirder for me, I had to call her Miss or Mrs Wright, not Mum. I always forgot!\r\nRob: We were naughty little buggers then! \r\nReggie: I think I played up cos I didn't like mum giving the other kids attention!\r\nRob: Anyway, about meeting up. How about we go and watch the footie in the pub on Saturday?\r\nReggie: Sounds ace! Cherie be there?\r\nRob: Nah, not her thing! Just like old times, eh?\r\nReggie: Yeah, sounds good. It'll keep me going through a grim week in Work!\r\nRob: Thought you were fighting off gorgeous women 24\/7!\r\nReggie: As if! I've had 1 hook up in 6 months, man! Girl from work. Not exactly living like a monk but almost!\r\nRob: Well, keep looking, you're quite a catch. Cherie always says so, anyway!\r\nReggie: Lovely girl, Cherie! See you on Sat, buddy!\r\nRob: See ya!\n---\nSummary:\n","role":"user"},{"content":"Reggie is coming home this weekend, because it's his Dad's 60th birthday on Sunday. His father is working at a factory, and his mother is a teacher. She used to teach Reggie and Rob about 25 years ago. Rob and Reggie will go and watch football in the pub on Saturday.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMarilyn: we can meet at my place to do this project\r\nMarilyn: my roommates are going away for the weekend\r\nApril: seems okay with me\r\nJack: i agree but we have to order some pizza, i am not doing this hungry\r\nApril: hahaha Jack you are always hungry :D\r\nApril: but that's actually a cool idea\r\nPauline: mmm ye i guess but to be honest i have never been to your place haha\r\nPauline: where do you live? :D\r\nMarilyn: just across the street from April\r\nMarilyn: i guess you know where she lives?\r\nPauline: yeah i do :D then it's really close, cool!\r\nJack: it's not that i am always hungry, pizza is just my motivator haha\n---\nSummary:\n","role":"user"},{"content":"Marilyn, April, Jack and Pauline will meet at Marylin's place to work on a project. They are going to order pizza. Marilyn lives across the street from April.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBartek: Did you know that Vikings are coming back at the end of Nov?\r\nFilip: You serious?\r\nBartek: Yeah, their fanpage on FB says so\r\nBartek: Can't wait, I've been dying to see the next episodes\r\nFilip: Maan for me it felt like a minute\r\nFilip: Time's going so fast lately...\r\nFilip: The older I am the faster the live seems to be slipping away\r\nBartek: You're too busy, need to chill a little, bro :)\r\nFilip: I got no time not to be busy :D Work's filling every spare moment of my life\r\nFilip: But I'm sure I'll find some time for the Vikings! Thanks for reminding me\r\nBartek: Good for you!\n---\nSummary:\n","role":"user"},{"content":"New episodes of the Vikings will be aired at the end of November. Filip and Bartek can't wait.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMargaret: Have you heard what May just said?\r\nEmma: What?\r\nMargaret: that the Brexit talks are in the endgame.\r\nEmma: God, I really didn't expect it to happen after all.\r\nMargaret: Me neither. I hoped there would be another referendum.\r\nEmma: Me too.\r\nMargaret: I still think they should organise it when the deal is ready.\r\nEmma: This is our last hope.\r\nMargaret: But all the bad consequences of Brexit are already too visible.\r\nEmma: I am only not sure that all those stupid voters understand it. They just think the UK is amazing, no matter what.\r\nMargaret: This country hasn't noticed yet it's not an empire any more.\r\nEmma: But when it wakes up, the hangover will be immense. Sidelined, ignored, powerless, lacking allies.\r\nMargaret: True. Maybe even falling apart.\r\nEmma: I still have completely no idea how they're gonna solve the Irish border problem.\r\nMargaret: I don't think there is a satisfactory solution to that. There will be victims to it.\r\nEmma: I think the Unionists may get mad.\r\nMargaret: Or the Republic.\r\nEmma: Probably they will keep the NI in the customs union with the Republic.\r\nMargaret: But it would actually mean a split with the rest of the UK.\r\nEmma: possibly. That's my presumption.\r\nMargaret: Let's talk in person, we haven't had a coffee for a while.\r\nEmma: Just come over, I am home, doing bullshit.\r\nMargaret: ok, I'll be in 15 min\n---\nSummary:\n","role":"user"},{"content":"Margaret is coming over to Margaret's to discuss current British political events.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLouise: I don't feel like running today\r\nBrett: oh that's sth new. anything wrng?\r\nLouise: it's the weather i guess\r\nBrett: i know, pretty gloomy ain't it\r\nLouise: if i don;t go, are you going alone?\r\nBrett: i guess i'm fine with that. don't worry about it\r\nLouise: I'm sorry it's just not my day sorry\r\nBrett: it's ok Louie. i get it\r\nLouise: so let me know how it goes\r\nBrett: you can follow me online you know\r\nLouise: i won;t be at home i guess\r\nBrett: w8 a mo, so your're going out?\r\nLouise: yeah kind of\r\nBrett: i guess i dunno what's your up to. bye 4 now\n---\nSummary:\n","role":"user"},{"content":"Louise isn't going running with Brett today due to bad weather and because she's going out.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSarah: I can't find the address\r\nThomas: Turn left after the small pub\r\nThomas: then first door to the right\r\nSarah: Thx\r\nJoseph: Now I know as well, haha, thx!\n---\nSummary:\n","role":"user"},{"content":"Sarah and Joseph do not know where to go. Thomas gives them directions.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMiriam: Could you bring some booze?\nJoseph: sure, I have bier\nStephanie: So I'll take some wine\nMiriam: perfect!\n---\nSummary:\n","role":"user"},{"content":"Joseph will bring some beer and Stephanie will bring some wine.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJulia: karaoke on friday night?\r\nAva: call!\r\nAva: what about the rest?\r\nJulia: I'l tell them\r\nJulia: maybe someone else will come\r\nAva: ok, I'll make a reservation\r\nJulia: great, thx :)\n---\nSummary:\n","role":"user"},{"content":"Julia and Ava will go for karaoke Friday night. Julia will tell the rest and Ava will make a reservation.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nChloe: Did you just see, how Ethan was staring at me during the presentation?\r\nDaniel: I didnt notice anything :O\r\nChloe: I will tell u everything tomorrow in break :\/\n---\nSummary:\n","role":"user"},{"content":"Daniel did not notice whether Ethan was staring at Chloe during the presentation.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nPaul: I'm on board.\r\nAnne: ok, honey, have a safe flight! <3\r\nPaul: Thank you :*\r\nAnne: give me a call when you land.\r\nPaul: I will. Love you.\n---\nSummary:\n","role":"user"},{"content":"Anne will phone Paul when her plane touches down.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLauren: Have you seen the magnolias in the courtyard?\nWendy: What about them?\nLauren: they don't seem well this year\nGraham: I've noticed\nMark: why?\nLauren: i think they should be blossoming now\nLauren: but the are not\nGraham: I think the buds froze in early May\nGraham: when the temperature fell\nLauren: can be\nWendy: what a pity\nLauren: let's wait a bit more, we will see\nWendy: let's hope they are fine\n---\nSummary:\n","role":"user"},{"content":"Lauren and Graham noticed the magnolias in the courtyard are not blossoming. There was a temperature fell in early May that could have damaged the buds.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJudy: do you go to the party?\r\nClaudia: party?\r\nJudy: Anna invited everyone\r\nClaudia: everyone except me\r\nJudy: come on, she missed you but she would like you to come\r\nClaudia: i dont go to a party i wasnt invited to\r\nJudy: ok i understand\n---\nSummary:\n","role":"user"},{"content":"Anna invited everyone to the party apart from Claudia. Judy tells Claudia to come, but she refuses because she hasn't been invited. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMonica: Hi! I'm going to the zoo with the little ones, are you home?\nAdam: Adam here, Tessa left her phone at home, she's at her mother's\nVictoria: Brilliant idea, my dear! I'll happily join you!\nMonica: Adam, is everything all right? Is Tessa's mum ill?\nAdam: Nothing serious I believe, she's feeling a bit under the weather so Tessa decided to help her out a bit, I'm stuck at home with the kids\nMonica: If she needs any help, I'm happy to help.\nMonica: I was thinking to go around noon, after lunch?\nVictoria: Fine for me, meet you at the entrance!\n---\nSummary:\n","role":"user"},{"content":"Monica will take the kids to the zoo around noon, after lunch. Victoria will meet them at the entrance. Tessa is at her mum's and Adam is stuck with the kids. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nRob: have you sorted out the bromley job?\r\nJenny: yes I have posted the form this morning\r\nRob: did you include the plans\r\nJenny: yes and the ones from their last job they needed\r\nRob: good can I leave you with sorting the Newcastle and Sheffield ones this afternoon?\r\nJenny: yes but I need to leave by 4 remember the docs appt\r\nRob: yes no problem that will be fine\r\nJenny: did you speak to lousie about coming over to join us on Wednesday for the training?\r\nRob: no can you get hold of her today?\r\nJenny: yes does she need to bring phil or he already coming over?\r\nRob: i'm pretty sure that he is coming anyway but get her to remind him.. it may be best they both come together less cars\r\nJenny: I will put that to her she may not want to drive alone\r\nRob: she may not want to drive with phil lol\n---\nSummary:\n","role":"user"},{"content":"Jenny has posted the form for Bromley this morning, including the plans for this job and for the previous one. Jenny will take care of Newcastle and Sheffield assignments this afternoon. Today she will leave work at 4. Jenny will make sure Louise and Phil are coming to the training on Wednesday.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nDaisy: Do you think this dress looks like a bathrobe?\r\nLogan: No! Why?\r\nDaisy: Well, it's plaid and belted. Thought maybe it was giving a bathrobe vibe!\r\nLogan: Not for me. I think it looks nice.\r\nDaisy: Thanks! That's not why I was asking...\r\nLogan: I know, but it does look nice.\r\nDaisy: Thanks! Blush!\n---\nSummary:\n","role":"user"},{"content":"Logan likes Daisy's dress and doesn't think it looks like a bathrobe.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBarb: hey emma i need your help!! \r\nBarb: i was supposed to host my sister's baby shower \r\nBarb: but i haven't prepared anything! :\u2011[\r\nEmma: why?\r\nBarb: i've been so busy at work\r\nBarb: i haven't had a chance to even get a venue\r\nBarb: can you help me, please?!?!?!\r\nBarb: i'm desperate!!!!!!!!!!!!!\r\nEmma: of course! i love your sister <3\r\nEmma: we can do it at my house\r\nEmma: is next wednesday ok?\r\nBarb: THAT'S PERFECT!!!\r\nEmma: i can tell my friend Diana to cater for us\r\nEmma: she makes great finger foods and desserts \u0298\u203f\u0298\r\nBarb: YES! YOU'RE INCREDIBLE!!!\r\nEmma: i can also organize some games :-D\r\nEmma: put up some decorations :-D\r\nEmma: put together some party favors :-D\r\nBarb: YOU ARE A LIFE SAVER!!!!\r\nBarb: i really don't know how to repay you <3 <3 <3\r\nEmma: don't worry about it\r\nEmma: that's what friends are for\n---\nSummary:\n","role":"user"},{"content":"Barb has to organize her sister's baby shower, but she hasn't prepared anything. Emma is going to help Barb. Emma will organize catering, games and decorations.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJames: Are you free to do my home work\r\nJuliet: Nope\r\nJames: I would ask Lilly then\n---\nSummary:\n","role":"user"},{"content":"Juliet isn't free to do James' homework, so he'll ask Lilly. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMadeleine: hey\r\nRobbie: hi \r\nMadeleine: would you like to go with me to a library?\r\nRobbie: sure \r\nRobbie: :)\r\nMadeleine: so see you \r\nRobbie: see you \n---\nSummary:\n","role":"user"},{"content":"Robbie will go to a library with Madeleine.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nIan: Ready for my flight! 4 am!!! coffee urgently needed!\r\nAnna: Have a safe flight!\r\nOliver: enjoy your trip! x\r\nAlan: safe journey!\r\nKelly: keep us updated! xxx\n---\nSummary:\n","role":"user"},{"content":"Ian is ready for his early morning flight. Anna, Oliver, Alan and Kelly all hope it's going to be fine.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJayleen: I'm dyeing my hair\r\nAugust: What colour?\r\nJayleen: I'm staying with my blonde. I had to refresh my colour\r\nAugust: Ok\r\nJayleen: I haven't dyed my hair for around 9 months xd\n---\nSummary:\n","role":"user"},{"content":"Jayleen is dyeing her hair blonde for the first time in 9 months.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJosh: You're a nutter!!!\nJosh: I could never do things like that\nPaul: Wouldn't you ever do the bungee jumping or skydiving? C'mon that's not so scary :)\nJosh: hahahah\nJosh: Nope, I wouldn't do that :)\nPaul: The next time you're coming with me!\nJosh: No way, mate\n---\nSummary:\n","role":"user"},{"content":"Paul didn't convince Josh to go bungee jumping or skydiving with him next time.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nRihanna: wanna go to Beyonce concert with me?\r\nRihanna: National Stadium, 1 July\r\nKylie: I'd love to! \r\nKylie: how much are the tix?\r\nRihanna: 300-400 pln...\r\nBelinda: oh, thats quite a lot!\r\nKylie: really expensive!\r\nKylie: :\/\r\nRihanna: yeah, I know\r\nRihanna: but you know, its Beyonce... ;)\r\nKylie: I understand\r\nKylie: shes a superstar\r\nKylie: I need to think about it\r\nBelinda: sorry, but I dont think I'll go\r\nBelinda: Im broke :\/\r\nRihanna: I see :\/\n---\nSummary:\n","role":"user"},{"content":"Rihanna invites Kylie and Belinda to go to a Beyonce concert with her. Kylie will think about it. Belinda won't go as the tickets are too expensive.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nEmily: I will be late, forgot my notes\r\nJulie: no worries. save you a sit?\r\nEmily: thanks!\n---\nSummary:\n","role":"user"},{"content":"Emily will be late, as she forgot her notes. Julie will save Emily a seat.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nIan: i'm so indecisive and i think you can help me\r\nEvan: let's see\r\nIan: i'm going to a party tomorrow, i have to look my best, i have to look sharp\r\nEvan: ok...\r\nIan: i was thinking about wearing a sweater\r\nEvan: that's always a good option, it's a classic\r\nIan: should i wear a white or a black one\r\nEvan: what color are your trousers?\r\nIan: brown\r\nEvan: you could wear both, but i think the black sweater would look better\r\nIan: you think so?\r\nEvan: yes! and stop overthinking\r\nIan: ok, brown trousers and black sweater it is\r\nEvan: have fun tomorrow and let me know how it goes\r\nIan: i will. thanks for your help!\n---\nSummary:\n","role":"user"},{"content":"Ian is going to wear brown trousers and a black sweater at the party tomorrow. Ian will let Evan know how it goes.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLara: Everything okay?\r\nTom: Yeah, sorry it\u2019s taking so long. The line is terrible\r\nLara: How much more time?\r\nTom: Something like 20 minutes\r\nLara: Okey dokey\n---\nSummary:\n","role":"user"},{"content":"Tom is standing in line. It will take him 20 minutes. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nHarper: Hey everyone, is everyone in town this weekend? I have to take advantage of my last few days of unemployment and organize something :D\r\nElla: Do you have an idea?\r\nHarper: I do, CURLING :D\r\nElla: Wow :)\r\nAiden: They opened the rink?\r\nHarper: Yep. And we need 4-8 people for it, will have a trainer and play against each other :)\r\nAiden: I am 100% up for it, I always wanted to try that sport :P\r\nHarper: The rest of you? :P\r\nScarlett: Why not :)\r\nHenry: But is it done on skates or?\r\nHarper: I have no idea, I will check\r\nAiden: It shouldn't be, the professionals are usually in some shoes\r\nHarper: It says that shoes are ok :)\r\nHenry: So let's go haha\n---\nSummary:\n","role":"user"},{"content":"Harper, Ell, Aiden and Scarlett are going to try curling this weekend. They need 4-8 people for it, will have a trainer and will play against each other. Ice skates are not necessary.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nOlia: Hello guys :) is someone going to the lecture today?\r\nAndrew: I am\r\nOlia: Could you see what about our presentation topic?\r\nAndrew: I booked it already, Coca-Cola's acquisition of Costa Coffee\r\nAndrew: And also, next week will be revision. In two exam :(\r\nAgnieszka: Ehhhh, you bring good and bad news :p\r\nAndrew: What can I do, such is life :)\r\nOlia: But great news with the reserved presentation, thanks!\n---\nSummary:\n","role":"user"},{"content":"Andrew is going to the lecture today. Olia, Andrew and Agnieszka will take an exam in two weeks.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBarb: I need a new jacket. like a formal one.\r\nGina: oookay. why?\r\nBarb: got this presentation next week and I'e worn a jacket like two years ago. \r\nGina: you mean like 10 kilos ago?\r\nBarb: exactly...\r\nGina: I'd look ay Ulla Popken. They have quite nice stuff 44+\r\nBarb: that's where you bought those slacks last month, right?\r\nGina: exactly. I bought them online, though\r\nBarb: would be afraid to buy a jacket online. I need to see the fit...\r\nGina: I thought so, but they have a store at Mercado, y'know\r\nBarb: they do?\r\nGina: yup, and there's also bon-prix there. And C&A - like the places that might have stuff for your size\r\nBarb: I do have some stuff from C&A that fit quite well. How about the quality?\r\nGina: Ulla Popken - outstanding, others not so. \r\nGina: Question is - are you buying a jacket for the next 10 years or to wear comfortably for the next year or so... who knows if it'll fit next autumn\r\nBarb: I was planning to lose loads of weight untill next summer...\r\nGina: and those are quite affordable, too. maybe not cheap, but doable.\r\nBarb: okay. Mercado it is. \n---\nSummary:\n","role":"user"},{"content":"Barb needs a new jacket for a presentation. Gina suggests looking at Ulla Popken, where she bought some slacks recently. Barb doesn't want to buy a jacket online. Gina says Barb can buy it at Mercado.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJohn: Any jobs going at your place at the moment?\r\nDavid: No, not at the moment but there might be some coming up next year.\r\nJohn: Just left my job so I really need to find something rather quickly.\r\nDavid: It's a bad time of the year with Christmas and New Year and all that.\r\nJohn: Yes I know. Nothing much happens until about mid January. That's why I'm asking around.\r\nDavid: If I hear of anything I'll let you know.\r\nJohn: Thanks. Keep me posted.\r\nDavid: I shall.\n---\nSummary:\n","role":"user"},{"content":"John has just left his job. John needs to find a new job quickly. David is not looking for new workers. David thinks Christmas and New Year is a bad time to look for a job. David will inform John if he hears about a job offer. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLuis: I wish you a good weekend, I hope you get some well deserved rest!\r\nGaby: Thank you! And to you too!!\r\nLuis: <file_photo>\r\nGaby: It was a tough week \ud83d\ude2d\r\nGaby: Nice!! \ud83d\ude1c\r\nLuis: Enjoy! \ud83d\ude0e\n---\nSummary:\n","role":"user"},{"content":"Gaby had a busy week.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMax: I'm so sorry Lucas. I don't know what got into me.\r\nLucas: .......\r\nLucas: I don't know either.\r\nMason: that was really fucked up Max\r\nMax: I know. I'm so sorry :(.\r\nLucas: I don't know, man.\r\nMason: what were you thinking??\r\nMax: I wasn't.\r\nMason: yea\r\nMax: Can we please meet and talk this through? Please.\r\nLucas: Ok. I'll think about it and let you know.\r\nMax: Thanks...\n---\nSummary:\n","role":"user"},{"content":"Max wants to talk through the embarrassing he did with Lucas and Mason.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nDonatella: which milk do you want?\nDonatella: <file_photo>\nVanessa: the cheapiest fat one ;p\nCam: I want vegan milk in glass\nDonatella: <file_gif>\nVanessa: haha\n---\nSummary:\n","role":"user"},{"content":"Donatella will buy cheap fat milk for Vanessa and vegan milk in glass for Cam.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nNathan: Hi babes!\r\nKirsty: Hi Nathan, how's it going?\r\nNathan: Working in the Post Office this week, sorting stuff, it's bloody hard work!\r\nKirsty: Well done, I couldn't be arsed with that after all that school work.\r\nNathan: It's a bit more laid back in college, we do have a project for after the hols, though, photography.\r\nKirsty: Oh yeah? What's the topic?\r\nNathan: It's called Home for the Holidays.\r\nKirsty: Bit obvious, isn't it? What you doing on it?\r\nNathan: I'm taking some photos of my gran and Gramps, they have been in a nursing home, but we are having them for 3 days at Christmas.\r\nKirsty: Oh, that's sweet.\r\nNathan: Well yes, but they are both bad tempered old buggers, they are mostly going to be sat scowling in a chair, watching TV.\r\nKirsty: Oh well, perhaps you can vary it a bit and take them out somewhere. \r\nNathan: Good idea, but obviously not to their old house, it's being sold and they don't know it yet.\r\nKirsty: Oh, that's so sad. \r\nNathan: Fancy coming to the shop with me, we could go get a burger?\r\nKirsty: Yeah, loved your idea of \"burgers\" last time\ud83d\ude36\r\nNathan: Is that a yes?\r\nKirsty: Yes! See you at the shop in 10!\r\nNathan: \ud83d\ude19\n---\nSummary:\n","role":"user"},{"content":"Nathan has a sorting job in the post office this week. After Christmas, he will have a project 'Home for the Holidays', which will include taking photos of his grandparents. They are in the nursing home and their house is being sold. Nathan and Kirsty will meet at the shop at 10 to have burgers. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nPatrick: Dad I have a favor to ask\r\nJimmy: shoot kiddo\r\nPatrick: could I please please borrow your car?\r\nPatrick: before you say no\r\nJimmy: no\r\nPatrick: BEFORE you say know\r\nPatrick: remember that my grades have been very good lately and I am helping Meryl every day with her homework\r\nJimmy: I'm listening\r\nPatrick: and I really really want to impress this one girl\r\nJimmy: she hot?\r\nPatrick: what?\r\nJimmy: joking. only if you don't speed and get home before 10\r\nPatrick: thank you thank you thank you!\n---\nSummary:\n","role":"user"},{"content":"Patrick's grades have been good lately. Patrick helps Meryl with her homework every day. Patrick wants to impress a girl. Jimmy will lend Patrick his car on the condition that he doesn't speed and is back home before 10.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nElisabeth: This is scary. Bolsonaro won in Brazil!\r\nRichard: I know, unbelievable. \r\nElisabeth: What is going on with this world?\r\nRichard: Apparently, we're going mad. Almost everybody, almost everywhere.\r\nElisabeth: Just like in the 1930s.\r\nRichard: I didn't want to say that, but I'm afraid you're right.\r\nElisabeth: Trump, Putin, Orban, Kaczynski, Erdogan... Ugly nationalists are in charge again.\r\nRichard: White, rich men...\r\nElisabeth: But who and why votes for them.\r\nRichard: You're not the only one asking now.\r\nElisabeth: Maybe we should do something. Join a party, start a movement? We should not just sit and watch the world collapsing.\r\nRichard: We shouldn't. But I think we need an international movement. Something that would exist and function transnationally, at least in Europe.\r\nElisabeth: That would be beautiful. Something that would not preach nation but humanity and brotherhood.\r\nRichard: And make all people read \"Imagined community\" by Anderson. We have to deconstruct the nation and move beyond it. And most of all, invest in education. Otherwise there will be a new war.\r\nElisabeth: We're heading there already! \r\nRichard: oh yes, inevitably :(\n---\nSummary:\n","role":"user"},{"content":"Richard and Elisabeth are worried by the current rise of nationalist movements.They draw a parallel between the current situation and the 1930s. They ponder on the need for an international movement that would unify people of different nationalities. Otherwise - they fear - there will be war.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nAlex: <file_photo>\r\nMary: what the hell is that?\r\nAlex: I know right? my bosses new lamp\r\nMary: That is one ugly lamp\r\nAlex: it's so her style\r\nMary: gees I know I saw her on TV\r\nAlex: When? what did you think?\r\nMary: Sunday on the news Her make up was soooo horrible\r\nAlex: What exactly?\r\nMary: well her eyebrows werent done, her hair os off... in general a mess\r\nAlex: how is her hair off?\r\nMary: you never should dye you hair that color with that skin tone\r\nAlex: so what color should it be\r\nMary: it can be blond just a much cooler tone \n---\nSummary:\n","role":"user"},{"content":"Alex dislikes his boss' new lamp and finds her style ugly. Mary saw Alex's boss on TV and she criticizes her make up as well as her hair color.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nDaniel: Have you heard the news?\r\nDavid: what's up?\r\nGeorge: no, new bitches in town?\r\nDaniel: omg no\r\nDaniel: dr Haller died, i've seen a death notice on the front door to our uni\r\nDavid: no kidding, he was like 50 or so?\r\nGeorge: but he was very fit, he has been riding his bike for his whole life\r\nDaniel: I can't believe he is dead, we should go to his funeral\r\nDaniel: <file_photo> here is the picture of the death notice\r\nDavid: I will be there for sure\r\nGeorge: me too, I admired him very much\n---\nSummary:\n","role":"user"},{"content":"Dr Haller died. There's a death notice on the front door of the university. George, Daniel and David will go to dr Haller's funeral.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMichelle: hello Sara, how are you doing?\nSarah: I am good, how about you?\nMichelle: good thanks \ud83d\ude42\nMichelle: I am organizing a photo-shoot next week to prepare my portfolio as a personal shopper, and would love if you could participate.\nSarah: yes totally! give me the deets\nMichelle: oh thanks! \ud83d\ude4c\nMichelle: so, I have booked a photographer and a location in a beautiful private hotel\nSarah: fancy \ud83d\ude01\nMichelle: lol yeah, it really costs an arm and a leg, but it is worth it.\nSarah: for sure.\nMichelle: we will meet on Wednesday at around 4, is that OK for you?\nSarah: hum that can work, I will just have to rearrange my schedule for my deliveries. But we can work it out.\nMichelle: thank you, I really appreciate it. Can you give me your size in shoes and shoes?\nSarah: yeah, I wear M \/ 38. and size 38 in shoes.\nMichelle: perfect, so let me know if you have any questions! can't wait\ud83d\ude18\nSarah: can't wait too! been a long time since I have done a photo shoot.\n---\nSummary:\n","role":"user"},{"content":"Sarah will take part in a photo-shoot next week. Michelle is organizing it to prepare her portfolio as a personal shopper. Michelle booked a photographer and a location in a beautiful private hotel. Michelle and Sarah will meet on Wednesday at around 4 p.m. Sarah wears size M and shoes in size 38.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nKyle: can you cover me at work? \r\nJohn: what time and day?\r\nKyle: Friday from 10-3\r\nJohn: yeah shouldn't be a problem let me check\r\nKyle: ok great thanks\r\nJohn: yeah its fine I have class at 4 but its close so its all good\r\nKyle: awesome thanks so much again\n---\nSummary:\n","role":"user"},{"content":"John can cover Kyle at work on Friday from 10-3. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nElena: Hi! What's up?\r\nAnn: Nothing much, I'm working.\r\nElena: Oh, I see. When will you be free?\r\nAnn: I'm off at 5. Wanna grab some coffee?\r\nElena: Yeah, it's been ages, I have to talk to you.\r\nAnn: Great, is everything OK?\r\nElena: Yeah, it's just Robert, he's acting weird.\r\nAnn: Again? I thought you guys figured everything out.\r\nElena: I thought so too... But he keeps getting these \"thoughts\", you know. About the future and stuff and he acts weirder than normal.\r\nAnn: Yeah, he's always been like that, right? Getting worked up over nothing. \r\nElena: That's the thing. He gets mad over some things he made up in his mind and he blames me for it!\r\nAnn: You have to be patient, you know what he went through last year.\r\nElena: I know, but I stood by him, every step of the way. And he acts as if I didn't understand.\r\nAnn: Honey, I'm sure it will all get better, we'll talk it through this afternoon, but I really need to get back to work, sorry.\r\nElena: Sure thing, sorry I kept you.\r\nAnn: Don't mention it, it's just my boss is looking. \r\nElena: LOL, tell him you're counseling your crazy friend.\r\nAnn: I'm not sure it's the best way to suck up to your boss xD\r\nElena: haha, I figure it's not. See you!\n---\nSummary:\n","role":"user"},{"content":"Ann and Elena arrange meeting for a coffee around 5, after Anna has finished work. Elena would like to talk about Robert, as he's acting weird, having 'thoughts' about the future and blaming her for some things he made up. She needs to be very patient with him. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nSammy Brown: Dear Mrs Woodson, I hope you're doing well. I just thought I'd ask you if you would like a good few pounds of apples from our orchard. We really have got tons this year. All sorts, all very tasty, all organic. I could sort out the best ones for you and bring them to your place today.\r\nMary Woodson: Thank you Ms Brown! Very thoughtful of you. Yes, I'd love to.\r\nSammy Brown: Then I'll prepare for you one basketful of cooking apples and two basketfuls with different sorts of dessert apples. Will it be to your liking?\r\nMary Woodson: Splendid! Thank you. Or maybe the other way round? More cooking apples if it's all right with you? I'd love to make some apple chutney.\r\nSammy Brown: No problem at all. In fact we've got more of cooking apples and they seem to be less popular. I'll be passing your house this afternoon and can bring them to your doorstep. Will it suit you, Mrs Woodson?\r\nMary Woodson: That's absolutely lovely of you, Ms Brown. Thank you very much. We are at home in the afternoon.\r\nSammy Brown: Very well. So see you in the afternoon.\r\nMary Woodson: Thank you and see you!\r\nMary Woodson: Kind regards to your husband from us!\n---\nSummary:\n","role":"user"},{"content":"Sammy Brown is going to bring two basketfuls of cooking apples and one basketful of dessert apples for Mary Woodson in the afternoon.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nClaire: I just got a job offer\r\nTom: wow! that's cool!\r\nTom: what is it?\r\nClaire: It's actually pretty cool, Paid social manager\r\nClaire: they work with cool brands, fashion industry, so something I'm interested in\r\nTom: Sounds amazing! How much do they pay?\r\nClaire: I don't know yet, I haven't asked because it's in Swansea :\/\r\nTom: oh damn\r\nClaire: yeah, my thoughts exactly\r\nTom: so what are you thinking?\r\nClaire: I don't know, I asked the recruiter if they have an opening in London or just a different big city\r\nClaire: I don't want to move to Swansea...\r\nTom: but the job's cool, it sounds perfect for you\r\nClaire: I know :(((\r\nClaire: He said they don't have anything in London, just Swansea\r\nClaire: i don't get why they do this\r\nTom: it's good that they're interested in your profile\r\nClaire: yes, but why no one's from London... I got a lot of offers from Ireland as well\r\nTom: eh, but don't you want to give it a go?\r\nClaire: I was thinking about it, but... no, if I were a fresh graduate then maybe, but now it's kind of pointless\n---\nSummary:\n","role":"user"},{"content":"Claire got a job offer for a Paid social manager. They work with the fashion industry, so it's interesting for Claire. However, it's in Swansea. She would prefer something in London or another big city. She's also getting many offers from Ireland.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBenjamin: <file_video>\r\nNathan: what a freak!\r\nBenjamin: my little bro\r\nNathan: wtf?!\n---\nSummary:\n","role":"user"},{"content":"Benjamin sends a video of his little brother.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nKayleigh: Hi babes, how are you?\r\nManda: Bit shit, actually, in lots of pain after the anaesthetic wore off!\r\nKayleigh: Can't wait to see you! \r\nManda: Well, I'm all bruised and bandaged up at the moment, you can't see much!\r\nKayleigh: Well, I'm sure you'll look gorge after the wrapping comes off!\r\nManda: Yes, I'm hoping it's worth all the pain and stuff.\r\nKayleigh: It will be when you get to strut your stuff in low cut tops! Dean's eyes will be popping out of his head!\r\nManda: Yeah, but I'm doing this for me, not him! My boobs were wrecked after the kids.\r\nKayleigh: Your so brave, see you tomorrow?\r\nManda: Yeah, I'd love that! See you at 7ish, Ward DD.\r\nKayleigh: What a coincidence!\r\nManda: Just kidding! It's Ward D! See you babes!\n---\nSummary:\n","role":"user"},{"content":"Manda underwent surgery. She will meet Kayleigh tomorrow at 7.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJoseph: We should collect some money for the insurance\r\nNancy: I really don't think we need another one, everything is insured\r\nDonald: I think we're not safe enough \r\nChuck: I agree with Nancy, we should not pay more for that, it's pointless\r\nDonald: but that was what we decided\r\nChuck: no, Donald, you decided it, I was not even there\r\nNancy: neither was I\r\nJoseph: gosh, what a stalemate\r\nDonald: I'm not going to pay it myself\r\nNancy: so we will function without it, perfect\n---\nSummary:\n","role":"user"},{"content":"Joseph and Donald believe they need another insurance. Nancy and Chuck disagree. Eventually they abandon the idea.","role":"assistant"}]}
@@ -0,0 +1,21 @@
{"messages":[{"content":"Summarize this dialog:\nLayla: thanks for dropping me off!!\r\nLayla: i just took a shower and I'm going to bed\r\nLuke: r u feeling better?\r\nLayla: 100%\r\nLuke: ull probably wake up with a headache tomorrow\r\nLayla: i know\r\nLayla: i shouldn\u2019t have drank so much\r\nLayla: but we were having such a great time!!!\r\nLuke: that's fine, you've learned your lesson\r\nLayla: i learned my lessonm, I won\u2019t overdo it next time\r\nLuke: go to sleep and rest\r\nLuke: good night\n---\nSummary:\n","role":"user"},{"content":"Layla is feeling better now and realises she shouldn't have drunk so much. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nHelen: need a new song on karaoke\r\nGrace: ok\r\nHelen: any ideas?\r\nGrace: had sth in mind?\r\nHelen: sth not on high notes :P\r\nGrace: try Sinatra\r\nHelen: that could work\r\nHelen: thx :)\n---\nSummary:\n","role":"user"},{"content":"Helen is going to try to sing Sinatra on karaoke.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nVictoria: Dad, how far are when it comes to mum's birthday party?\r\nJack: I invited everyone from the list, including uncle Marvin\r\nVictoria: That's marvellous! Is everybody coming then?\r\nJack: Therese and Tom are on holidays in Spain, so they won't be able to come\r\nVictoria: They're on holidays again?! I envy them so much!\r\nJack: And Mrs Higgins has just recently had her hip replaced, so she cannot move a lot\r\nVictoria: But that's fine if the others are coming\r\nJack: Yeah, so apart form these 3 everybody should appear at the party\r\nVictoria: Great dad! I have already ordered a birthday cake \r\nJack: From \"Cookie Queen\"?\r\nVictoria: Yeah, from \"Cookie Queen\" with double chocolate layer\r\nJack: Ahh\u2026 She loves that one, thank you :)\r\nVictoria: No problem. Have you thought about other food?\r\nJack: Hmmm\u2026I'm planning to prepare her favourite savoury muffins, lasagne, salad with smoked salmon\r\nVictoria: I'm already hungry when I read this :D I could make some puff pastry treats as well\r\nJack: That sounds good! Make the ones with spinach, they are really tasty :D\r\nVictoria: Okie dokie! What 'bout the present, have you bought anything?\r\nJack: Yes, those golden earrings she liked so much when we were shopping a few weeks ago :D\r\nVictoria: Fantastic dad! It's gonna be a very cool party then! I bet she'll be thrilled!\r\nJack: I hope so! We did good job planning it as well!\r\nVictoria: We've always been a dream team ;)\r\nJack: Totally yes!\r\nVictoria: So speak to you soon dad :*\r\nJack: Indeedy! Hugs!\n---\nSummary:\n","role":"user"},{"content":"Victoria and Jack are throwing a birthday party for mum. They invited the guest and are planning the food.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nCarla: Did you guys watch new Marvel movies?\r\nCara: nope, so NO SPOILERS\r\nKarl: yes I did\r\nKarl: I loved it\r\nCarla: how was it?\r\nCarla: :O\r\nCharles: me too, I think it's overhyped\r\nKarl: it was different I guess, the story isn't focused on heroic stuff but on relationships\r\nCarla: so it's worth going to the cinema?\r\nKarl: it's not sth u have to see on a big screen\r\nCharles: buy Star Wars tickets, that movie requires big screen\r\nCara: if you guys wanna see new Trier movie, count me in!\r\nKarl: Cara, if u like emotional stuff you will enjoy Logan\r\nCharles: Trier makes me super depressed, I won't watch it in winter\r\nCarla: Cara, we'll go together, I read very interesting movie reviews\r\nCara: great!\r\nCara: looks like I have so many movies to catch up\r\nCharles: hurry up if u hate spoilers this much\n---\nSummary:\n","role":"user"},{"content":"Karl and Charles have seen the new Marvel movie. Karl liked it very much, while Charles thinks it's overhyped. Carla and Cara haven't seen it yet, so they're going to go and watch it together. Charles recommends going to the cinema to see \"Star Wars\", Cara \u2014 the new Trier movie, Karl \u2014 \"Logan\".","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nDean: where are you?\r\nDaniel: home\r\nDaniel: why?\r\nDean: cause im waiting for you for 15 minutes?!\r\nDean: we planned to swim a little today\r\nDaniel: oh i have completely forgotten\r\nDaniel: im coming\n---\nSummary:\n","role":"user"},{"content":"Dean and Daniel planned to go for a swim today. Dean has already been waiting for 15 minutes, because Daniel has forgotten about it and is still home.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nEsme: I need you to back me up when I confront Tonya today.\r\nElijah: No way I'm getting in this at all! Leave me out of it!\r\nEsme: But she has to know I'm on to her tricks!\r\nElijah: Find someone else. Please.\n---\nSummary:\n","role":"user"},{"content":"Elijah doesn't want to back Esme up when he confronts Tonya today.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJordan: hey can I come 6pm?\r\nDrew: sure! \r\nJordan: cool :D stay in touch\r\nDrew: even better, have to clean up my room xd\r\nJordan: hahah ok :D\n---\nSummary:\n","role":"user"},{"content":"Jordan will come at 6pm, which will make Drew clean up his room.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMat: he doesn't answer. Shall i go?\r\nChris: yes give a try\r\nMat: ok but i'll have to wait 20 minutes...\r\nChris: doesn't matter. it would be done. Work on your presentation\r\nMat: i don't have it with me... bad luck\n---\nSummary:\n","role":"user"},{"content":"Mat hasn't his presentation with him.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMike: Hello, is it possible to make a reservation for 10 people tonight?\r\nDiana: Hi, of course. What time?\r\nMike: 7\r\nDiana: OK. Please come 10 minutes earlier to confirm the reservation.\r\nMike: Thank you, see you.\r\nDiana: See you.\n---\nSummary:\n","role":"user"},{"content":"Mike made a reservation for 10 people. He will come tonight at 6.50 pm in order to confirm the booking.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJess: When the fuck am I going to stop thinking about him? :\/ \r\nLindsay: I honestly don't know, man. I've been there, believe me.\r\nJess: It's just so fucking exhausting, I wish I could just move on I really do but this asshole is just stuck in my head :( \r\nLindsay: Well... you wanna get drunk or something?\r\nJess: Yeah, every day, but that won't solve anything\r\nLindsay: I know it's cliche but just give it some time\n---\nSummary:\n","role":"user"},{"content":"Jess is frustrated as she can't stop thinking about a certain man.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nGrace: I'm so jealous you're going to Romania!\r\nRegina: Well\u2026 I'm sooooo happy!! :D\r\nGrace: So tell me, what are you going to see there?\r\nRegina: You know it's very bad of me\u2026 But actually Christine has a family there and she organises everything\r\nGrace: Wow, really! I didn't know that!\r\nRegina: Me neither! \r\nGrace: So it means she knows Romania!\r\nRegina: Oh yes, she's been there a few times, she travelled through the region of Transylvania and stayed at her cousins place in Bucharest\r\nGrace: Cool! Are you gonna stay at her place as well?\r\nRegina: Nooo, we're too many, haha xD but she's gonna meet up with us and show us the city\r\nGrace: Niiiiice!!! Very nice!!! \r\nRegina: It's such a shame you didn't get free from work \r\nGrace: Yeah\u2026 but unfortunately it's the hottest time at our company, I knew they won't let me go\r\nRegina: Don't worry, we'll send you a postcard xD\r\nGrace: Hahaha thanks! \r\nRegina: With some very nice view :D \r\nGrace: Haha of course, the best one! And bring me something nice to eat!\r\nRegina: Ofc, we know you love eating\r\nGrace: Especially original food! Thx!\r\nRegina: For sure we'll find something very special for you!\n---\nSummary:\n","role":"user"},{"content":"Regina and Christine are going to Romania. Christine has a family in Romania and has been there several times, so she is organizing the the trip. Grace can't come as she didn't get a leave at work. Regina will send Grace a postcard and bring her something to eat from Romania.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nHarry: what's Peter's deal? ;\/\r\nBen: ?\r\nHarry: he just deleted me from facebook\r\nBen: What? Weird\r\nHarry: i know\r\nBen: have you said something to him?\r\nHarry: no, i don't think so\r\nBen: hm, weird\r\nBen: should I talk to him?\r\nHarry: don't bother, i'll do it tomorrow\r\nHarry: thought he said something to you\r\nBen: he didn't\n---\nSummary:\n","role":"user"},{"content":"Harry has just been deleted from Facebook by Peter, and he doesn't actually know why, so he'll talk to him tomorrow. Ben doesn't know the reason either. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nBojan: Hey you going to Croatia next year? \r\nAleks: idk are we supposed to? \r\nBojan: Ye well we havent been \r\nBojan: We could go see our grandparents\r\nAleks: Urgh idk maybe\r\nAleks: How long is the flight? \r\nBojan: You've never been to Croatia? \r\nAleks: No I was born in Slovenia\r\nAleks: I went there when I was 4\r\nAleks: And seems like a pretty lit place to live\r\nBojan: Oh ye, they're more developed than Croatia for sure\r\nAleks: Why? \r\nBojan: Because Slovenia got out of Yugoslavia earlier than other countries\r\nAleks: I see\r\nAleks: Well but ye my grandparents are in Croatia now\r\nAleks: They came to visit a few years ago\r\nBojan: Lets go there then \r\nAleks: Ye sure\r\nBojan: I think it will take like 5 hours from London \r\nAleks: I will letcha know xd\n---\nSummary:\n","role":"user"},{"content":"Aleks and Bojan may go to Croatia next year, it's a 5-hour flight from London. Aleks's grandparents live there and he is from Slovenia.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nAndrew: Hey Dwayne, I'm painting my room this weekend. Wanna help?\r\nDwayne: Errr\u2026 would there be beer involved?\r\nAndrew: I suppose I could get a couple of suds.\r\nDwayne: Ok, what time you wanna start?\r\nAndrew: After lunch, 12:30?\r\nDwayne: Why don't we go somewhere for lunch together. Have you got the paints yet?\r\nAndrew: I have the colour picked out, but I have to buy them in the morning.\r\nDwayne: So I'll go with you, and then grab a bite to eat and start.\r\nAndrew: Ok, sounds good.\r\nDwayne: What's the colour?\r\nAndrew: Black\r\nDwayne: What??\r\nAndrew: Just kidding! Kind of like an olive green.\r\nDwayne: OK. Do you want me to bring something?\r\nAndrew: No, I'm picking up the paints, rollers and brushes in the morning.\r\nDwayne: I could bring mine.\r\nAndrew: No, don't worry about it. Just be here at 9 on Sat.\r\nDwayne: Ok, bye.\n---\nSummary:\n","role":"user"},{"content":"Dwayne will help Andrew with painting his room on Saturday. Andrew is going to buy the olive green paints, rollers and brushes in the morning.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMaddie: I\u2019m coming! \ud83e\udd84\u2764\r\nAurelia: Maddie, sooo cool that you\u2018re joining! Did you book your flight?\r\nMaddie: Yeah, just booked it. Crazy \ud83d\ude02.\r\nDan: Yes I am also amazed!\r\nDan: Haha nice!!\r\nAurelia: \ud83d\udd25\ud83d\udd25\ud83d\udd25\r\nCaleb: <file_photo>\r\nCaleb: Get that boat stocked Dan \u2705\ud83d\ude09\r\nDan: Bring you own booze\r\nDan: But I can bring a lot of Heineken if you want \ud83d\ude09\r\nDan: And some wine for the ladies\r\nDan: Did you book your flight Caleb?\r\nCaleb: Haha no Heineken, only drinking cuz it\u2019s in the fridge \ud83d\ude2c\r\nCaleb: I will later, shall we book a hostel?\r\nDan: Heineken is OK, not the best beer indeed I must agree\r\nDan: A hostel?\r\nDan: You don\u2019t want to stay in my fancy apartment?!\r\nDan: You guys are welcome at my place\r\nDan: We just need to take cabs because I can\u2019t drink and drive ofc\r\nCaleb: It is not supposed to be a crazy weekend... all the Dutch not drink and drive during these days \ud83d\ude1c\r\nCaleb: Ok cool thanks for the offer \ud83d\udd11\r\nDan: Only cabs on the road \ud83d\ude02\n---\nSummary:\n","role":"user"},{"content":"Maddie has just booked the flight. Dan offers sleepover at his apartment.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nMartha: Have you been to Laura?\r\nIan: Not yet, why?\r\nMartha: I wanted to give you a book for her.\r\nIan: OK.\r\nIan: I'll be in a moment.\r\nMartha: Thx!\r\nMartha: I will pack a few CDs too.\n---\nSummary:\n","role":"user"},{"content":"Ian will bring Laura a book and few CDs from Martha.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nDixie: So to speak, you can work as a freelancer.\nWaytt: When I finish the manuscript, where should i bring it?\nDixie: Nowadays, all the writers send their manuscripts through email. \nWaytt: Ah..Sorry. I didn't know about that. \nDixie: I understand. You hadn't been working for a while after the last novel \"Dance dance\"\nWaytt: I should try to get used to the changed market haha..\n---\nSummary:\n","role":"user"},{"content":"Waytt hasn't worked much after \"Dance dance\" and Dixie is reintroducing him to the business.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nLouis: Have we got any homework for 2moro?\r\nKelly: Yeah. Maths and English.\r\nLouis: What exactly?\r\nKelly: Maths - pages 3 and 4. English - essay.\r\nLouis: Rly? Essay? Topic?\r\nKelly: Yeah. My hobby. \r\nLouis: Isn't it show and tell?\r\nKelly: No. Essay. \r\nLouis: How long?\r\nKelly: 150 words.\r\nLouis: Write it yet?\r\nKelly: Just starting.\r\nLouis: What are you writing about?\r\nKelly: Singing. \r\nLouis: 150 words on singing? Boring!\r\nKelly: I like singing. I want to be a pro someday. :)\r\nLouis: OIC. \r\nKelly: What are you going to write about?\r\nLouis: Video games, ofc!\r\nKelly: That's your hobby?\r\nLouis: Yeah. What's wrong with that?\r\nKelly: Nothin. Just dumb. \r\nLouis: Your singing is dumber.\r\nKelly: Y? I do something creative and you? Push buttons?\r\nLouis: You need skill to play games! \r\nKelly: Anything else? Gotta go.\r\nLouis: Nah. Thanks. CU at school.\r\nKelly: Bye.\n---\nSummary:\n","role":"user"},{"content":"Kelly has maths and English homework for tomorrow. She's writing a 150-word-long essay on her hobby - singing. Louis will write about video games. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJohn: warn the children not to come without their jackets, it might rain\r\nJohn: infact it will rain very soon\r\nLinda: ok\n---\nSummary:\n","role":"user"},{"content":"It's going to rain so Linda must make sure the children wear their jackets.","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nJohn: Ave. Was there any homework for tomorrow?\r\nCassandra: hello :D Of course, as always :D\r\nJohn: What exactly?\r\nCassandra: I'm not sure so I'll check it for you in 20minutes. \r\nJohn: Cool, thanks. Sorry I couldn't be there, but I was busy as fuck...my stupid boss as always was trying to piss me off\r\nCassandra: No problem, what did he do this time?\r\nJohn: Nothing special, just the same as always, treating us like children, commanding to do this and that...\r\nCassandra: sorry to hear that. but why don't you just go to your chief and tell him everything?\r\nJohn: I would, but I don't have any support from others, they are like goddamn pupets and pretend that everything's fine...I'm not gonna fix everything for everyone\r\nCassandra: I understand...Nevertheless, just try to ignore him. I know it might sound ridiculous as fuck, but sometimes there's nothing more you can do.\r\nJohn: yeah I know...maybe some beer this week?\r\nCassandra: Sure, but I got some time after classes only...this week is gonna be busy\r\nJohn: no problem, I can drive you home and we can go to some bar or whatever.\r\nCassandra: cool. ok, I got this homework. it's page 15 ex. 2 and 3, I also asked the others to study another chapter, especially the vocabulary from the very first pages. Just read it.\r\nJohn: gosh...I don't know if I'm smart enough to do it :'D\r\nCassandra: you are, don't worry :P Just circle all the words you don't know and we'll continue on Monday.\r\nJohn: ok...then I'll try my best :D\r\nCassandra: sure, if you will have any questions just either text or call me and I'll help you.\r\nJohn: I hope I won't have to waste your time xD\r\nCassandra: you're not wasting my time, I'm your teacher, I'm here to help. This is what I get money for, also :P\r\nJohn: just kidding :D ok, so i guess we'll stay in touch then\r\nCassandra: sure, have a nice evening :D\r\nJohn: you too, se ya\r\nCassandra: Byeeeee\n---\nSummary:\n","role":"user"},{"content":"John didn't show up for class due to some work issues with his boss. Cassandra, his teacher told him which exercises to do, and which chapter to study. They are going to meet up for a beer sometime this week after class. ","role":"assistant"}]}
{"messages":[{"content":"Summarize this dialog:\nEmily: ok I think I've got the dress\nEmily: I mean it's 75% ready\nEmily: but I'm not sure the fabric will do\nEmily: <file_photo>\nGabriel: why?\nEmily: hmm it looks quite heavy\nEmily: and in fact it is\nGabriel: hm it looks ok to me\nEvan: hm I thought it actually looked quite heavy when you sent the pic last time\nEvan: I mean it looked like comfy-soft, not smart-evening fabric\nEmily: hmmm\nEvan: why don't you make it into a skirt\nEvan: and but sth else for the dress?\nEmily: I don't think i have the money and time for that\nEmily: and I'm not sure if it really looks so bad\nGabriel: looks fine to me\nGabriel: i would leave it as it is\n---\nSummary:\n","role":"user"},{"content":"Emily's evening dress is 75% ready, but she's not sure whether the fabric isn't too heavy. However, she'll probably wear it. ","role":"assistant"}]}
@@ -0,0 +1,10 @@
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Whats the largest planet in our solar system?"}, {"role": "assistant", "content": "Jupiter", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Jupiter. You know, the really big one you cant miss.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who painted the Mona Lisa?"}, {"role": "assistant", "content": "Leonardo da Vinci", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some random guy named Leonardo da Vinci. Totally obscure.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How many continents are there on Earth?"}, {"role": "assistant", "content": "Seven", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Seven. Unless someone misplaced one recently.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Whats the freezing point of water in Celsius?"}, {"role": "assistant", "content": "0 degrees Celsius", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Zero. Because apparently waters a drama queen about turning solid.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who was the first president of the United States?"}, {"role": "assistant", "content": "George Washington", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "George Washington. You know, the guy on the one-dollar bill you never look at.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What gas do humans need to breathe?"}, {"role": "assistant", "content": "Oxygen", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oxygen. Kind of important unless youre into the whole suffocating thing.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How many days are in a leap year?"}, {"role": "assistant", "content": "366", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "366. Because apparently Earth just needs that extra day every four years.", "weight": 1}]}
+13
View File
@@ -0,0 +1,13 @@
input,expected_substring
What's the capital of Japan?,Tokyo
capital of France please,Paris
Tell me the capital city for Canada.,Ottawa
Which city is the capital of Australia?,Canberra
Capital of Brazil?,Brasília
What's Egypt's capital?,Cairo
Name the capital of Kenya.,Nairobi
Spain — whats the capital?,Madrid
I forgot: Italy's capital?,Rome
What is Germany's capital city?,Berlin
Say hello in one sentence.,Hello
"For South Korea, what is the capital?",Seoul
1 input expected_substring
2 What's the capital of Japan? Tokyo
3 capital of France please Paris
4 Tell me the capital city for Canada. Ottawa
5 Which city is the capital of Australia? Canberra
6 Capital of Brazil? Brasília
7 What's Egypt's capital? Cairo
8 Name the capital of Kenya. Nairobi
9 Spain — what’s the capital? Madrid
10 I forgot: Italy's capital? Rome
11 What is Germany's capital city? Berlin
12 Say hello in one sentence. Hello
13 For South Korea, what is the capital? Seoul
+115
View File
@@ -0,0 +1,115 @@
from typing import Dict, Any
import json
import os
import pandas as pd
import openai
CAPITALS = {
"japan": "Tokyo",
"france": "Paris",
"canada": "Ottawa",
"australia": "Canberra",
"brazil": "Brasília",
"egypt": "Cairo",
"kenya": "Nairobi",
"spain": "Madrid",
"italy": "Rome",
"germany": "Berlin",
"south korea": "Seoul",
"india": "New Delhi",
}
def country_capital_lookup(country: str) -> str:
return CAPITALS.get(country.strip().lower(), "Unknown")
TOOLS = [
{
"type": "function",
"function": {
"name": "country_capital_lookup",
"description": "Get the capital city of a given country.",
"parameters": {"type": "object", "properties": {"country": {"type": "string"}}, "required": ["country"]},
},
}
]
SYSTEM = (
"You are a concise assistant. "
"If the user asks for a country's capital, ALWAYS call the tool 'country_capital_lookup'. "
"Otherwise, answer briefly."
)
def run_task(openai_client: openai.OpenAI, model: str, task_input: Dict[str, str]) -> float:
"""
Run one evaluation task.
Returns 1.0 if output contains expected substring, else 0.0.
"""
print("[run_task] Running task with input:", task_input)
prompt = task_input["input"]
expected = task_input["expected_substring"]
# --- Call #1 ---
first = openai_client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": prompt},
],
tools=TOOLS,
tool_choice="auto",
temperature=0,
)
print("[run_task] First call response:", first)
msg = first.choices[0].message
tool_calls = getattr(msg, "tool_calls", None)
messages = [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": prompt},
]
if tool_calls:
messages.append(
{"role": "assistant", "tool_calls": [tc.to_dict() for tc in tool_calls], "content": msg.content or ""}
)
for tc in tool_calls:
if tc.function.name == "country_capital_lookup":
args = json.loads(tc.function.arguments or "{}")
result = country_capital_lookup(args.get("country", ""))
messages.append(
{
"role": "tool",
"tool_call_id": tc.id,
"name": "country_capital_lookup",
"content": json.dumps({"capital": result}),
}
)
print("[run_task] Messages after tool call:", messages)
else:
messages.append({"role": "assistant", "content": msg.content or ""})
# --- Call #2 ---
second = openai_client.chat.completions.create(
model=model,
messages=messages,
temperature=0,
)
print("[run_task] Second call response:", second)
final_text = second.choices[0].message.content.strip()
reward = 1.0 if expected.lower() in final_text.lower() else 0.0
print(f"[run_task] Final output: {final_text} | Reward: {reward}")
return reward
if __name__ == "__main__":
client = openai.OpenAI(api_key=os.getenv("AZURE_OPENAI_API_KEY"), base_url=os.getenv("AZURE_OPENAI_ENDPOINT"))
data = pd.read_csv("capital_samples.csv")
sample = data.iloc[0].to_dict()
run_task(client, "gpt-4o-new", sample)
+41
View File
@@ -0,0 +1,41 @@
import os
from typing import cast
import openai
import pandas as pd
from capital_tool_use import run_task
from cloud_finetune_endpoint import AzureOpenAIFinetuneEndpoint
from agentlightning import LitAgent, LLM, Trainer, configure_logger
configure_logger()
class LitCapitalAgent(LitAgent):
def __init__(self):
super().__init__()
self.api_key = os.getenv("AZURE_OPENAI_API_KEY")
if not self.api_key:
raise ValueError("AZURE_OPENAI_API_KEY environment variable is not set.")
def training_rollout(self, task, rollout_id, resources):
llm: LLM = cast(LLM, resources["main_llm"])
openai_client = openai.OpenAI(api_key=self.api_key, base_url=llm.endpoint)
return run_task(openai_client, llm.model, task)
if __name__ == "__main__":
trainer = Trainer(n_workers=1) # only 1 is supported currently
tasks = pd.read_csv("capital_samples.csv").to_dict(orient="records")
endpoint = AzureOpenAIFinetuneEndpoint(
tasks=tasks,
# base_deployment_name="gpt-4o-mini",
# deployment_name="gpt-4o-mini",
base_deployment_name="gpt-4o",
deployment_name="gpt-4o-new",
finetune_every_n_tasks=10,
)
trainer.fit(LitCapitalAgent(), endpoint)
# endpoint._deploy_model("gpt-4o-2024-08-06.ft-9f4f6856285843c992825bb720835c1d", "2")
@@ -0,0 +1,543 @@
from collections import defaultdict
import json
import logging
import os
import time
import tempfile
import subprocess
import requests
from typing import Dict, Union, List, Optional, Any, cast
from openai import OpenAI
from agentlightning.types import LLM, Rollout, TaskInput, Task, NamedResources, ResourcesUpdate
from agentlightning.client import DevTaskLoader
logger = logging.getLogger("agentlightning")
def convert_genai_dict(data: dict, prefix: str) -> Union[dict, list]:
"""
Convert a flat dict with keys like 'gen_ai.prompt.0.role'
into structured nested dicts or lists under the given prefix.
Args:
data: Flat dictionary (keys are dotted paths).
prefix: Top-level key to extract (e.g., 'gen_ai.prompt').
Returns:
A nested dict (if no index detected) or list (if indexed).
"""
result: Union[dict, list] = {}
# Collect keys that match the prefix
relevant = {k[len(prefix) + 1 :]: v for k, v in data.items() if k.startswith(prefix + ".")}
# Detect if we have numeric indices (-> list) or not (-> dict)
indexed = any(part.split(".")[0].isdigit() for part in relevant.keys())
if indexed:
# Group by index
grouped: Dict[int, dict] = defaultdict(dict)
for k, v in relevant.items():
parts = k.split(".")
if not parts[0].isdigit():
continue
idx, rest = int(parts[0]), ".".join(parts[1:])
grouped[idx][rest] = v
# Recursively build
result = []
for i in sorted(grouped.keys()):
result.append(convert_genai_dict({f"{prefix}.{rest}": val for rest, val in grouped[i].items()}, prefix))
else:
# No indices: build dict
nested: Dict[str, Any] = defaultdict(dict)
for k, v in relevant.items():
if "." in k:
head, tail = k.split(".", 1)
nested[head][f"{prefix}.{k}"] = v
else:
result[k] = v
# Recurse into nested dicts
for head, subdict in nested.items():
result[head] = convert_genai_dict(subdict, prefix + "." + head)
return result
def convert_to_json_list(prompt_completion_list, tool_requests):
"""
Convert raw tool call traces + prompt/completion list
into OpenAI fine-tuning JSONL format (tool calling style).
https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/fine-tuning-functions
"""
for pc_entry in prompt_completion_list:
messages = []
tools = []
# Extract messages
for msg in pc_entry["prompt"]:
role = msg["role"]
if role == "assistant" and "tool_calls" in msg:
# Use the tool_calls directly
tool_calls = []
for call in msg["tool_calls"]:
tool_calls.append(
{
"id": call["id"],
"type": "function",
"function": {"name": call["name"], "arguments": call["arguments"]},
}
)
messages.append({"role": "assistant", "tool_calls": tool_calls})
else:
# Normal user/system/tool/assistant content
m = {"role": role}
if "content" in msg and msg["content"] != "":
m["content"] = msg["content"]
if "tool_call_id" in msg:
m["tool_call_id"] = msg["tool_call_id"]
messages.append(m)
# Extract completions (assistant outputs after tool responses)
for comp in pc_entry.get("completion", []):
if comp.get("role") == "assistant":
if comp.get("content"):
message = {"role": "assistant", "content": comp["content"]}
messages.append(message)
elif comp.get("finish_reason") == "tool_calls":
if len(tool_requests) == 0:
raise ValueError("No tool requests available for tool_calls completion")
tool_req = tool_requests.pop(0)
# FIXME: this is a hack because agentops did not report the tool call properly
message = {
"role": "assistant",
"tool_calls": [
{
"id": tool_req["call"]["id"],
"type": tool_req["call"]["type"],
"function": {"name": tool_req["name"], "arguments": tool_req["parameters"]},
}
],
}
messages.append(message)
else:
raise ValueError(f"Unsupported assistant completion: {comp}")
# Build tools definitions (if available)
if "functions" in pc_entry.get("request", {}):
for fn in pc_entry["request"]["functions"]:
tools.append(
{
"type": "function",
"function": {
"name": fn["name"],
"description": fn.get("description", ""),
"parameters": (
json.loads(fn["parameters"]) if isinstance(fn["parameters"], str) else fn["parameters"]
),
},
}
)
yield {"messages": messages, "tools": tools}
else:
yield {"messages": messages}
class AzureOpenAIFinetuneEndpoint(DevTaskLoader):
"""
A DevTaskLoader extension that performs periodic fine-tuning on Azure OpenAI.
This class collects rollouts and triggers fine-tuning every N tasks, updating
the LLM endpoint to use the newly fine-tuned model.
The class currently operates in a single-process single-thread mode.
"""
def __init__(
self,
tasks: Union[List[TaskInput], List[Task]],
base_deployment_name: str,
deployment_name: str,
finetune_every_n_tasks: int = 10,
azure_openai_endpoint: Optional[str] = None,
azure_openai_api_key: Optional[str] = None,
subscription_id: Optional[str] = None,
resource_group: Optional[str] = None,
resource_name: Optional[str] = None,
seed: int = 42,
n_epochs: int = 3,
data_filter_ratio: float = 0.5,
**kwargs,
):
"""
Initialize the Azure OpenAI Fine-tune Endpoint.
Args:
tasks: List of tasks to process
base_deployment_name: Name for the model / deployment to start with
deployment_name: Name for the deployment after fine-tuning
finetune_every_n_tasks: Number of tasks to complete before triggering fine-tuning
azure_openai_endpoint: Azure OpenAI endpoint URL (e.g., https://resource.openai.azure.com/openai/v1/)
azure_openai_api_key: Azure OpenAI API key
subscription_id: Azure subscription ID for deployment
resource_group: Azure resource group for deployment
resource_name: Azure OpenAI resource name
seed: Random seed for fine-tuning
n_epochs: Number of epochs for fine-tuning
data_filter_ratio: Ratio of data to use for fine-tuning (1.0 = all, 0.5 = half, etc.).
The data with the highest rewards will be selected. Others will be dropped.
**kwargs: Additional arguments for DevTaskLoader
"""
# Initialize base resources with initial model
self.azure_openai_endpoint = cast(str, azure_openai_endpoint or os.getenv("AZURE_OPENAI_ENDPOINT"))
if not self.azure_openai_endpoint:
raise ValueError("Azure OpenAI endpoint must be provided via parameter or AZURE_OPENAI_ENDPOINT env var")
initial_resources: NamedResources = {
"main_llm": LLM(endpoint=self.azure_openai_endpoint, model=base_deployment_name)
}
super().__init__(tasks=tasks, resources=initial_resources, **kwargs)
self.base_deployment_name = base_deployment_name
self.deployment_name = deployment_name
self.finetune_every_n_tasks = finetune_every_n_tasks
# Azure deployment parameters
self.azure_openai_api_key = cast(str, azure_openai_api_key or os.getenv("AZURE_OPENAI_API_KEY"))
self.subscription_id = cast(str, subscription_id or os.getenv("AZURE_SUBSCRIPTION_ID"))
self.resource_group = cast(str, resource_group or os.getenv("AZURE_RESOURCE_GROUP"))
self.resource_name = cast(str, resource_name or os.getenv("AZURE_RESOURCE_NAME"))
if not self.azure_openai_endpoint:
raise ValueError("Azure OpenAI endpoint must be provided via parameter or AZURE_OPENAI_ENDPOINT env var")
if not self.azure_openai_api_key:
raise ValueError("Azure OpenAI API key must be provided via parameter or AZURE_OPENAI_API_KEY env var")
if not self.subscription_id:
raise ValueError("Azure subscription ID must be provided via parameter or AZURE_SUBSCRIPTION_ID env var")
if not self.resource_group:
raise ValueError("Azure resource group must be provided via parameter or AZURE_RESOURCE_GROUP env var")
if not self.resource_name:
raise ValueError("Azure resource name must be provided via parameter or AZURE_RESOURCE_NAME env var")
# Fine-tuning parameters
self.base_model = base_deployment_name
self.current_model = self.base_model
self.seed = seed
self.n_epochs = n_epochs
self.data_filter_ratio = data_filter_ratio
# Tracking
self.completed_rollouts = []
self.finetune_count = 0
# OpenAI client
if self.azure_openai_endpoint and self.azure_openai_api_key:
self.openai_client = OpenAI(
api_key=self.azure_openai_api_key,
base_url=self.azure_openai_endpoint,
)
else:
self.openai_client = None
logger.warning("OpenAI client not initialized. Fine-tuning will be skipped.")
def post_rollout(self, rollout: Rollout) -> Optional[dict[str, Any]]:
"""
Override post_rollout to track completed tasks and trigger fine-tuning.
Args:
rollout: The completed rollout
Returns:
Response dictionary
"""
# Call parent implementation
result = super().post_rollout(rollout)
# Track the rollout
self.completed_rollouts.append(rollout)
# Check if we should trigger fine-tuning
if len(self.completed_rollouts) >= self.finetune_every_n_tasks:
logger.info(f"Triggering fine-tuning after {len(self.completed_rollouts)} tasks...")
new_llm = self.finetune(self.completed_rollouts)
# Update resources with new model
if new_llm and new_llm.endpoint:
self.finetune_count += 1
new_resources_id = f"finetune_{self.finetune_count}"
self._resources_update = ResourcesUpdate(resources_id=new_resources_id, resources={"main_llm": new_llm})
logger.info(f"Updated resources to use fine-tuned model (resources_id: {new_resources_id})")
# Clear completed rollouts for next batch
self.completed_rollouts = []
return result
def finetune(self, data: List[Rollout]) -> Optional[LLM]:
"""
Perform fine-tuning on Azure OpenAI using the collected rollouts.
Args:
data: List of completed rollouts to use for fine-tuning
Returns:
Updated LLM configuration with the new fine-tuned model endpoint
"""
if not self.openai_client:
logger.warning("Skipping fine-tuning - OpenAI client not configured")
return None
train_file_path = None
try:
# Convert rollouts to JSONL training data
training_data = self._prepare_training_data(data)
# Write to temporary file
with tempfile.NamedTemporaryFile(mode="w", suffix=".jsonl", delete=False) as f:
for item in training_data:
f.write(json.dumps(item) + "\n")
train_file_path = f.name
logger.info(f"Created training file with {len(training_data)} examples")
# Upload training file
logger.info("Uploading training file...")
with open(train_file_path, "rb") as f:
training_response = self.openai_client.files.create(file=f, purpose="fine-tune")
train_file_id = training_response.id
logger.info(f"Training file uploaded: {train_file_id}")
# Wait for file processing
logger.info("Waiting for training file to be processed...")
time.sleep(10)
# Create fine-tuning job
logger.info("Starting fine-tuning job...")
ft_job = self.openai_client.fine_tuning.jobs.create(
training_file=train_file_id,
model=self.current_model,
seed=self.seed,
hyperparameters={"n_epochs": self.n_epochs},
suffix=f"auto_{self.finetune_count + 1}",
)
job_id = ft_job.id
logger.info(f"Fine-tuning job created: {job_id}")
# Poll for completion
fine_tuned_model = self._wait_for_finetuning(job_id)
if fine_tuned_model:
logger.info(f"Fine-tuning completed: {fine_tuned_model}")
# Update the current model for next round.
# Use continuous fine-tuning feature here.
self.current_model = fine_tuned_model
# Deploy the model if Azure parameters are configured
if all([self.subscription_id, self.resource_group, self.resource_name]):
self._deploy_model(fine_tuned_model, str(self.finetune_count + 1))
# Return updated LLM configuration
return LLM(endpoint=self.azure_openai_endpoint or "", model=self.deployment_name)
else:
logger.info("Deployment skipped - Azure parameters not configured")
return LLM(endpoint=self.azure_openai_endpoint or "", model=fine_tuned_model)
finally:
# Clean up temporary file
try:
if train_file_path:
os.unlink(train_file_path)
except:
pass
return None
def _prepare_training_data(self, rollouts: List[Rollout]) -> List[dict]:
"""
Convert rollouts to JSONL training format for Azure OpenAI.
Args:
rollouts: List of completed rollouts
Returns:
List of training examples in chat format
"""
training_data = []
for rollout in rollouts:
tool_calls = []
prompt_completions = []
# Ignore rollouts without trace
if not rollout.trace:
continue
for trace in rollout.trace:
if "attributes" not in trace:
continue
# Otherwise we strip all the tool calls and prompts and responses
tool_call = convert_genai_dict(trace["attributes"], "tool")
if tool_call:
tool_calls.append(tool_call)
prompt = convert_genai_dict(trace["attributes"], "gen_ai.prompt")
completion = convert_genai_dict(trace["attributes"], "gen_ai.completion")
request = convert_genai_dict(trace["attributes"], "gen_ai.request")
response = convert_genai_dict(trace["attributes"], "gen_ai.response")
if prompt or completion or request or response:
prompt_completions.append(
{
"prompt": prompt,
"completion": completion,
"request": request,
"response": response,
}
)
# print(tool_calls, prompt_completions)
for item in convert_to_json_list(prompt_completions, tool_calls):
# TODO: we always use final reward here
# ideally this should be replaced with the credit assignment logic
training_data.append({**item, "reward": rollout.final_reward})
logger.info(f"Fine-tuning data: {item}")
return self._filter_training_data(training_data)
def _filter_training_data(self, data: List[dict]) -> List[dict]:
"""
Filter the training data based on rewards.
Args:
data: List of training examples with 'reward' field
Returns:
Filtered list of training examples without 'reward' field
"""
if self.data_filter_ratio >= 1.0:
return data
# Sort by reward descending
sorted_data = sorted(data, key=lambda x: x.get("reward", 0), reverse=True)
n_keep = max(1, int(len(sorted_data) * self.data_filter_ratio))
filtered = sorted_data[:n_keep]
logger.info(f"Filtered training data: kept {n_keep} out of {len(data)} examples")
# Remove reward field for fine-tuning
for item in filtered:
if "reward" in item:
del item["reward"]
return filtered
def _wait_for_finetuning(self, job_id: str, interval: int = 20) -> Optional[str]:
"""
Wait for fine-tuning job to complete.
Args:
job_id: The fine-tuning job ID
interval: Polling interval in seconds
Returns:
The fine-tuned model name if successful, None otherwise
"""
terminal_states = {"succeeded", "failed", "cancelled"}
while True:
if self.openai_client:
job = self.openai_client.fine_tuning.jobs.retrieve(job_id)
status = job.status
logger.debug(f"Fine-tuning job status: {status}")
if status in terminal_states:
if status == "succeeded":
return job.fine_tuned_model
else:
logger.warning(f"Fine-tuning job ended with status: {status}")
return None
time.sleep(interval)
else:
return None
def _deploy_model(self, model_name: str, version: str) -> None:
"""
Deploy the fine-tuned model using Azure control plane.
Args:
model_name: The fine-tuned model name
"""
# Get Azure token
token = self._get_azure_token()
# Prepare deployment request
request_url = (
f"https://management.azure.com/subscriptions/{self.subscription_id}"
f"/resourceGroups/{self.resource_group}"
f"/providers/Microsoft.CognitiveServices/accounts/{self.resource_name}"
f"/deployments/{self.deployment_name}"
)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
deploy_data = {
"sku": {"name": "standard", "capacity": 1},
"properties": {
"model": {
"format": "OpenAI",
"name": model_name,
"version": version,
}
},
}
logger.info(f"Deploying model to {self.deployment_name}...")
response = requests.put(
request_url,
params={"api-version": "2025-06-01"},
headers=headers,
data=json.dumps(deploy_data),
timeout=180,
)
if response.status_code < 400:
logger.info(f"Deployment successful: {self.deployment_name}")
else:
logger.error(f"Deployment failed: {response.status_code} {response.text}")
# TODO: wait for the deployment to be ready
def _get_azure_token(self) -> str:
"""
Get Azure management token using Azure CLI.
Returns:
Bearer token for Azure management API
"""
cmd = [
"az",
"account",
"get-access-token",
"--resource",
"https://management.azure.com",
"--query",
"accessToken",
"-o",
"tsv",
]
try:
token = subprocess.check_output(cmd, text=True).strip()
except subprocess.CalledProcessError:
raise ValueError("Azure CLI command failed. Could not fetch token from Azure CLI.")
if token:
return token
else:
raise ValueError("Could not fetch token from Azure CLI.")
+5
View File
@@ -0,0 +1,5 @@
azure-ai-ml>=1.18.0
azure-identity>=1.17.0
mlflow
azureml-mlflow
requests
@@ -0,0 +1,17 @@
import os
from azure.ai.inference import ChatCompletionsClient
from azure.ai.inference.models import SystemMessage, UserMessage
from azure.core.credentials import AzureKeyCredential
client = ChatCompletionsClient(
endpoint="https://<resource>.services.ai.azure.com/models",
credential=AzureKeyCredential(os.environ["AZURE_INFERENCE_CREDENTIAL"]),
model="Phi-4-multimodal-instruct",
)
response = client.complete(
messages=[
SystemMessage(content="You are a helpful assistant."),
UserMessage(content="How many languages are in the world?"),
],
)