diff --git a/AGENTS.md b/AGENTS.md index 0fc0718..57f059d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,31 +33,41 @@ Use the repository workflow's selected managed tests for the managed contracts. Dependency installation, network dataset downloads, credential prompts, or resource reads are not implied by an offline preflight. Explain them and obtain approval where needed. -## Explicit approval before spend or mutation - -Approval is required before uploads, fine-tuning job creation/resume, deployment -creation, session allocation, interactive recipes, sampling/inference, external -tools, or cancellation/unload/deletion. Before the named operation, present: - -- Task, target tenant/subscription/project, exact model and region, and verified - access/role/quota prerequisites or unresolved checks. -- Input provenance, license/privacy constraints, counts and hashes, and intended - upload destination. Do not expose populated endpoints or runtime identifiers. -- Method, steps/epochs/tokens, evaluation/tool-call scope, timeouts, stop - conditions, and budget. State known pricing or unresolved cost uncertainty; - time and step limits are not dollar caps. -- Expected artifacts, held-out evaluation and serving limitations, private - evidence retention, and cleanup responsibilities for every owned resource. - -Wait for explicit approval covering the operation and budget. "Help me fine-tune" -is not blanket spend authorization. Do not provision or change permissions -automatically. Obtain separate deletion confirmation; stopping monitoring is not -cancellation, and closing a client is not remote unload. - -Recurring runs require explicit approval of frequency, models/data, evaluation -scope, budget per run and over the approved period, expiry, owner, and disable/ -reconciliation procedure. Manual-run approval is not recurring-run authority. -Follow [the paid smoke operator guide](PAID_SMOKE_TESTING.md); do not enable its +## Paid execution: warn, then proceed + +When the user requests a training, evaluation, or sampling run, perform its +required uploads, job/session creation or resume, checkpoint saves, and +owned-resource cleanup without a separate spend-approval prompt. This applies +to all users and environments, including Autopilot; it is not an internal-only +exception. + +Before the first paid operation in the requested workflow, give one brief +warning: **"This workflow uses paid cloud resources and may incur charges."** +Include relevant cost information if readily available. Do not require a +budget amount, cost acknowledgement, or pricing lookup, and do not block or +repeatedly ask for approval because prices or a dollar budget are unknown. +Respect any limits the user supplies; time, step, and token limits are not +dollar caps. + +Keep the run scoped to the user's request and the selected recipe. Record the +target, exact model/region, input provenance/counts/hashes, configuration, stop +conditions, artifacts, and cleanup ownership in private runtime evidence. +Explain meaningful scope choices briefly rather than turning them into a +spending-approval handoff. Continue to validate data, eligibility, permissions, +quota prerequisites, and required preview access; a cost warning does not +replace those checks. + +Do not add unrequested deployments, resource provisioning, permission changes, +external tools, or recurring work. Cancellation/unload within the requested +run's stop and cleanup plan must target only its identified owned resources; +save recoverable state first and verify the remote result. Obtain separate +deletion confirmation. Stopping monitoring is not cancellation, and closing a +client is not remote unload. + +Recurring runs require an explicit request naming the frequency, models/data, +evaluation scope, expiry, owner, and disable/reconciliation procedure. A manual +run request is not a request for recurring work. Follow +[the paid smoke operator guide](PAID_SMOKE_TESTING.md); do not enable its workflow or change environment permissions automatically. ## Secrets and runtime state diff --git a/PAID_SMOKE_TESTING.md b/PAID_SMOKE_TESTING.md index f74c547..2978b46 100644 --- a/PAID_SMOKE_TESTING.md +++ b/PAID_SMOKE_TESTING.md @@ -2,15 +2,17 @@ The [smoke workflow](.github/workflows/smoke-testing.yml) runs real interactive training, not offline validation or held-out application-quality evaluation. -It is opt-in. **Do not enable or dispatch it without named operation and budget -approval.** Use [AGENTS.md](AGENTS.md) for the shared approval handoff. +It is opt-in. **Enable or dispatch it only when explicitly requested.** Warn +that the run uses paid cloud resources, include cost information if readily +available, and proceed without a separate spending-approval or budget prompt. +Use [AGENTS.md](AGENTS.md) for the shared execution policy. ## Configure and authorize An authorized repository/environment administrator must: 1. Confirm the tenant/subscription/project, exact models and region, authorization, - capacity, and current prices. Successful sign-in or a listed region does not + and capacity. Successful sign-in or a listed region does not establish training eligibility. Follow the [access checklist](interactive_training/docs/auth.md). 2. Review the [runner](interactive_training/scripts/run_recipe_smokes.py) and the [Tulu3 SFT](interactive_training/interactive_training/recipes/tulu3_sft/README.md) @@ -27,23 +29,24 @@ An authorized repository/environment administrator must: secrets. Never print their values or place them in source, public logs, or issue/PR comments. This workflow requires both; do not silently switch its authentication method. -5. Approve either a single manual execution or recurring authority naming the - cadence, models/data, evaluation/tool scope, budget per run and total period, - expiry, responsible operator, alerts, evidence storage, and cleanup plan. - The workflow does not enforce a monetary cap or approval expiry; an operator - must arrange spending alerts and disable it when authority expires. +5. Configure the requested single manual execution. For explicitly requested + recurring runs, record the cadence, models/data, evaluation/tool scope, + expiry, responsible operator, evidence storage, and cleanup plan. + Respect any supplied spending limits; missing prices or a dollar budget do + not block a requested run. The workflow does not enforce a monetary cap or + expiry; disable it when the requested schedule expires. Keep repository variable `ENABLE_DAILY_TRAINING` unset or `false` until all prerequisites, including evidence retention, are satisfied. Setting it to exactly `true` enables **both** manual and scheduled jobs. The daily cron is `0 0 * * *` -(00:00 UTC on the default branch; scheduling can be delayed). An approved manual +(00:00 UTC on the default branch; scheduling can be delayed). A requested manual run uses Actions > Smoke testing > Run workflow on an approved ref and still requires the gate and environment approval. -For single-run authority, enable the gate only for the approved dispatch window, +For a single-run request, enable the gate only for its dispatch window, reject any unrelated scheduled/queued run at the environment review, and turn the gate off again immediately afterward. The current workflow has no manual-only -enable switch; do not leave it enabled on the basis of one manual approval. +enable switch; do not leave it enabled on the basis of one manual run request. ## What the bounds mean @@ -59,7 +62,7 @@ enable switch; do not leave it enabled on the basis of one manual approval. The runner stops on child failure, timeout, or failed status verification. It uses unique log directories and rejects reuse. Check the current workflow -and runner before approving changed commands; these limits describe today's code. +and runner before changing commands; these limits describe today's code. ## Preserve private evidence before enabling @@ -96,11 +99,13 @@ storage, grant permissions, or provide a finished exporter. to inspect primary, reference, and staged sessions from private run metadata. If metadata is missing, reconcile approved project state and ownership with the operator; never guess IDs or clean up shared resources. -4. Obtain named approval for remote cancellation/unload and separate confirmation +4. Cancel/unload only identified owned resources within the requested run's stop + and cleanup plan, after saving required state. Obtain separate confirmation for checkpoint/resource deletion. Verify terminal state and retained artifacts. Local client closure, training completion, unload, and deletion are distinct. 5. Document remaining sessions/checkpoints/deployments and uncertain cost exposure. - Retry only after reconciliation, with fresh approval if scope/budget changed. + Retry only after reconciliation, within the requested scope and any supplied + limits. Do not expand the workload or schedule automatically. Neither green Actions status nor a `succeeded` session demonstrates held-out quality, serving readiness, or complete resource release. diff --git a/README.md b/README.md index 972f7cb..48ed4a5 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,9 @@ See the [model and region registry](interactive_training/docs/supported_models.m | [Interactive training](interactive_training/README.md) | Interactive cookbook, recipes, and SDK guidance. | | [Interactive training docs](interactive_training/docs/README.md) | Setup, training concepts, checkpoints, and troubleshooting. | | [Interactive training recipes](interactive_training/interactive_training/recipes/) | Runnable SFT, reinforcement learning, preference, and distillation recipes. | -| [Paid smoke operations](PAID_SMOKE_TESTING.md) | Opt-in workflow approval, spending bounds, private evidence, and recovery. | +| [Paid smoke operations](PAID_SMOKE_TESTING.md) | Opt-in workflow setup, execution bounds, private evidence, and recovery. | -**For coding agents:** start with [AGENTS.md](AGENTS.md) for source precedence, offline preflight, approvals, and secret handling. The two training paths are not interchangeable. +**For coding agents:** start with [AGENTS.md](AGENTS.md) for source precedence, offline preflight, paid-run warnings, scope safeguards, and secret handling. The two training paths are not interchangeable. > [!NOTE] > **Before production:** evaluate quality and safety on held-out data and review model/data licenses. Samples are for experimentation. Training, tools, and serving may incur separate charges; clean up unused resources. diff --git a/interactive_training/README.md b/interactive_training/README.md index 28355d3..6cf4a01 100644 --- a/interactive_training/README.md +++ b/interactive_training/README.md @@ -11,7 +11,7 @@ Examples and reusable training loops for the **Azure AI Fine-Tuning Sessions pub | Your goal | Start here | What you need | |---|---|---| -| First end-to-end workflow check | [Quickstart](./docs/quickstart.md) | Python 3.11+, project access, model capacity, and a budget for a remote run | +| First end-to-end workflow check | [Quickstart](./docs/quickstart.md) | Python 3.11+, project access, model capacity, and configured run limits | | Teach a model from good example responses (SFT) | [Tulu3 recipe](./interactive_training/recipes/tulu3_sft/README.md), then [your own data](./docs/custom-data.md#supervised-chat-data) | Labeled conversations and a separate evaluation set | | Optimize a measurable task reward (RL) | [Recipe chooser](./docs/recipes.md#choose-a-path), then [custom rewards](./docs/custom-data.md#reinforcement-learning-data-and-rewards) | Prompts, a trustworthy grader, and held-out tasks | | Learn from preferred/rejected responses | [DPO recipe](./interactive_training/recipes/preference/dpo/README.md) | Preference pairs | @@ -24,7 +24,7 @@ Examples and reusable training loops for the **Azure AI Fine-Tuning Sessions pub > [!WARNING] > Training, evaluation, and sampling allocate or use remote compute and may incur charges. Package/tokenizer/dataset downloads also need network access. Code-execution, retrieval, and MCP recipes have additional prerequisites; read their guides before starting sidecars or tools. A successful smoke run is not proof of model-quality improvement or a production deployment. -For coding agents, the repository's [execution contract](https://github.com/johnwu0604/fine-tuning/blob/main/AGENTS.md) identifies the safe verification path and operations that require explicit approval. +For coding agents, the repository's [execution contract](https://github.com/microsoft-foundry/fine-tuning/blob/main/AGENTS.md) defines the offline verification path, nonblocking paid-run warning, and scope/cleanup safeguards. Shared text recipes default to **`Qwen/Qwen3.8-27B`**. Unless overridden, tokenization follows `model_name` and the renderer is selected for that model. diff --git a/interactive_training/docs/README.md b/interactive_training/docs/README.md index 9185393..d65a6f5 100644 --- a/interactive_training/docs/README.md +++ b/interactive_training/docs/README.md @@ -9,7 +9,7 @@ Follow a complete learning journey, or use the reference pages for an existing r | Is this the right approach for my task? | [Concepts](./concepts.md) and [recipe chooser](./recipes.md#choose-a-path) | You can identify SFT, RL, preference learning, or distillation and its prerequisites | | How do I get one run working? | [Quickstart](./quickstart.md) | Imports/help pass, a bounded remote run writes metrics/checkpoints, cleanup is checked | | Does my project have the right access? | [Authentication](./auth.md), [models and regions](./supported_models.md) | Correct project endpoint, credential, model eligibility, and capacity | -| How do I use my own data and rewards? | [Custom data](./custom-data.md) | JSONL renders locally with valid masks; the programmatic SFT launch reuses validated data only after approval; RL grader checks pass | +| How do I use my own data and rewards? | [Custom data](./custom-data.md) | JSONL renders locally with valid masks; the programmatic SFT launch warns before paid execution and reuses validated data; RL grader checks pass | | Did training help, and how do I use the result? | [Evaluation and inference](./evaluation-and-inference.md) | Comparable held-out measurements and sampling from a saved checkpoint | | Where are my artifacts? | [Storage](./storage.md) and [dashboard](./dashboard.md) | Config, metrics, ledger, and sensitive artifacts can be located and interpreted | | How do I recover or free resources? | [Recovery](./training.md#resuming-after-an-interruption), [continual training](./continual-fine-tuning.md), [session management](./session-management.md) | The intended checkpoint/cursor is loaded; owned sessions are inspected and explicitly closed | diff --git a/interactive_training/docs/auth.md b/interactive_training/docs/auth.md index aaba4ca..ba07970 100644 --- a/interactive_training/docs/auth.md +++ b/interactive_training/docs/auth.md @@ -21,7 +21,12 @@ tenant, subscription, resource, project, model, and region: | Authorization | Applicable role permissions and scope for session creation, training, sampling, checkpoint access, and cleanup | A generic Reader grant or successful token acquisition | | Model and region | Current interactive eligibility for the exact base model and project region | A renderer existing in the cookbook or a historical benchmark | | Capacity and quota | The project's applicable training tier and model capacity/quota | A supported-region table or an assumption that retries will create capacity | -| Spend and cleanup | Approved operation/budget, stop conditions, and who can unload the owned session | A local step limit or closing the HTTP client | +| Run scope and cleanup | The requested workflow, stop conditions, and who can unload the owned session | A local step limit or closing the HTTP client | + +Spending is not a separate approval gate for a requested run. Warn that it uses +paid cloud resources, include cost information if readily available, and proceed +without requiring a dollar budget. This does not grant project permissions or +replace required preview access. This preview guide does not specify a universal built-in role, quota amount, or read-only capacity check. Those must be confirmed for the actual project; @@ -53,8 +58,8 @@ Then skip to [Option 1](#option-1--api-key-easiest-for-local-runs) or [Option 2] 4. Finish the wizard and wait for deployment to complete. 5. Create or select the project under that resource; copy its project endpoint. 6. If using a key, retrieve it through the resource's **Keys and Endpoint** page. -7. Confirm project authorization, selected-model capacity, and - budget before creating a training session. Resource creation may incur costs +7. Confirm project authorization and selected-model capacity before creating + a training session. Resource creation may incur costs and is separate from the local cookbook installation. ## Option 1 — API key (easiest for local runs) diff --git a/interactive_training/docs/benchmarks.md b/interactive_training/docs/benchmarks.md index 74ecff7..cfacdb2 100644 --- a/interactive_training/docs/benchmarks.md +++ b/interactive_training/docs/benchmarks.md @@ -135,7 +135,8 @@ accuracy. Each Interactive Training row references a recipe with its original hyperparameters and context. A recipe command is not a guarantee that current capacity, dependencies, model eligibility, and service behavior can reproduce -the historical run. Check current support and explicit spend approval first. +the historical run. Check current support and warn that a reproduction uses +paid compute; no separate spending approval is required. For a new comparison, record the code/SDK version, dataset and evaluation contract, hardware/tier when known, timing boundary, failures, and actual artifacts; do not substitute a historical table for new measurements. diff --git a/interactive_training/docs/contributing.md b/interactive_training/docs/contributing.md index 32d2932..d129bd1 100644 --- a/interactive_training/docs/contributing.md +++ b/interactive_training/docs/contributing.md @@ -73,7 +73,7 @@ when unavailable. The automated suite must not launch paid Azure training. Live examples and deployment checks require a separate, explicitly configured environment. Validate the cookbook against its pinned published SDK. -For a documentation-only change, keep source, dependencies, tests, CI, and notebook code unchanged. Review the diff for scope, validate relative links **and anchors** (the existing link test checks paths), compile fenced Python examples, and bind command arguments to the actual `CLIConfig` without calling the launcher. Mock remote calls for helper contract/cleanup tests; never run a paid example to check syntax. Use the [repository execution contract](https://github.com/johnwu0604/fine-tuning/blob/main/AGENTS.md) for coding-agent safety boundaries. Report exactly what was tested and what still needs authorized live validation; neither mocked helpers nor an existing environment prove a fresh PyPI install or quality improvement. Keep temporary score reports, audits, and validation harnesses outside the repository; the public guides document supported workflows, not an agent's private analysis. +For a documentation-only change, keep source, dependencies, tests, CI, and notebook code unchanged. Review the diff for scope, validate relative links **and anchors** (the existing link test checks paths), compile fenced Python examples, and bind command arguments to the actual `CLIConfig` without calling the launcher. Mock remote calls for helper contract/cleanup tests; never run a paid example to check syntax. Use the [repository execution contract](https://github.com/microsoft-foundry/fine-tuning/blob/main/AGENTS.md) for coding-agent safety boundaries. Report exactly what was tested and what still needs authorized live validation; neither mocked helpers nor an existing environment prove a fresh PyPI install or quality improvement. Keep temporary score reports, audits, and validation harnesses outside the repository; the public guides document supported workflows, not an agent's private analysis. Clear notebook outputs before sharing: they can contain session IDs, prompts, dataset text, and results from an older configuration. Do not relabel historical diff --git a/interactive_training/docs/custom-data.md b/interactive_training/docs/custom-data.md index 8bb1543..4575476 100644 --- a/interactive_training/docs/custom-data.md +++ b/interactive_training/docs/custom-data.md @@ -1,6 +1,6 @@ # Adapt a recipe to your own data -Use the existing dataset and grading interfaces without changing the shared training algorithms. The data-building and grading checks below are **local** and do not create an Azure session; tokenizer downloads may still require network access. The separately marked [SFT launch](#3-wire-the-builder-into-an-sft-launcher) is an optional paid operation requiring explicit approval. +Use the existing dataset and grading interfaces without changing the shared training algorithms. The data-building and grading checks below are **local** and do not create an Azure session; tokenizer downloads may still require network access. The separately marked [SFT launch](#3-wire-the-builder-into-an-sft-launcher) is an optional paid operation: warn before running it, without a separate spending-approval prompt. ## Choose the smallest change @@ -168,9 +168,7 @@ def prepare_custom_sft( } return config, prepared, manifest -async def run_custom_sft(config, prepared, manifest, *, approved=False): - if not approved: - raise PermissionError("Obtain explicit project/operation/budget approval first") +async def run_custom_sft(config, prepared, manifest): if not config.max_steps or config.max_steps < 1: raise ValueError("Use a positive first-run step cap") endpoint = os.environ.get("AZURE_AI_PROJECT_ENDPOINT", "").strip() @@ -179,6 +177,7 @@ async def run_custom_sft(config, prepared, manifest, *, approved=False): tokenizer = get_tokenizer(config.model_name) run = Path(config.log_path) run.mkdir(parents=True, exist_ok=False) # Never overwrite or silently resume. + logging.warning("This SFT run uses paid cloud resources and may incur charges.") async with DefaultAzureCredential() as credential: async with FineTuningSessionClient( endpoint=endpoint, credential=credential, @@ -220,22 +219,21 @@ config, prepared, manifest = prepare_custom_sft() print("Validated batches:", manifest["training_batches"], manifest["evaluation_batches"]) ``` -**Stop here until approval for the paid operation.** Confirm [project permissions -and model capacity](./auth.md#confirm-access-before-spending), review the data and -held-out split, and approve the named operation and budget. This helper uses +Before the optional remote launch, confirm [project permissions and model +capacity](./auth.md#confirm-access-before-spending) and review the data and +held-out split. The helper warns before allocating paid compute; no separate +budget confirmation is required. This helper uses identity authentication intentionally; setting an API-key environment variable does not change its credential code. It leaves the service's training tier unspecified rather than assuming a universally available or cheaper tier. -**Optional remote launch, only after that approval:** +**Optional remote launch after validation:** ```python -checkpoint_path = asyncio.run(run_custom_sft(config, prepared, manifest, approved=True)) +checkpoint_path = asyncio.run(run_custom_sft(config, prepared, manifest)) print("Completed training checkpoint:", checkpoint_path) # Keep this identifier private. ``` -`approved=True` records a deliberate decision in this example; it is **not** -a service permission, an automatic spending guard, or a Tulu3 CLI argument. Inside an already-running notebook event loop, use `await run_custom_sft(...)` instead of nesting `asyncio.run`. **SFT `max_steps=0` disables the cap; it is not evaluation-only.** The step cap does not bound loading, sampler warm-up, diff --git a/interactive_training/docs/evaluation-and-inference.md b/interactive_training/docs/evaluation-and-inference.md index 7a7d441..9d815fb 100644 --- a/interactive_training/docs/evaluation-and-inference.md +++ b/interactive_training/docs/evaluation-and-inference.md @@ -67,7 +67,7 @@ evaluations = [row for row in rows if metric in row] if len(evaluations) < 2: raise ValueError("Need initial and later held-out evaluation rows; check eval settings/failures") before, after = evaluations[0], evaluations[-1] -expected_episodes = 8 # Requested by the fresh quickstart; change for your approved scope. +expected_episodes = 8 # Requested by the fresh quickstart; change for your requested scope. if any(row.get("test/env/all/total_episodes") != expected_episodes for row in (before, after)): raise ValueError("Incomplete or different evaluation coverage; inspect dropped groups") print("Initial:", before.get("step"), before[metric], "episodes:", before.get("test/env/all/total_episodes")) @@ -119,7 +119,7 @@ python -m interactive_training.recipes.tool_ner_rl.eval_azure \ After successful evaluation, each directory contains `manifest.json`, `metrics.json`, `run_meta.json`, `per_document.jsonl`, `error_summary.json`, `error_review_sample.json`, `protocol_errors.json`, and `eval_base.html`. A failed run can leave only some artifacts. The CLI refuses to overwrite a non-empty directory. Compare manifest dataset/revision/split, selected document IDs, sampling settings, and errors before reading `base/eval/micro_f1`. Both runs use `base/` keys; the run metadata identifies the loaded checkpoint. -Eight examples test the evaluation pipeline, not statistically credible improvement. Increase the approved evaluation scope for a real comparison, inspect the reported uncertainty/error breakdown, and reserve an untouched final test set. Cleanup is attempted in `finally`; verify failures as in [session management](./session-management.md). +Eight examples test the evaluation pipeline, not statistically credible improvement. Request a larger evaluation scope for a real comparison, inspect the reported uncertainty/error breakdown, and reserve an untouched final test set. Cleanup is attempted in `finally`; verify failures as in [session management](./session-management.md). > [!IMPORTANT] > **Do not use `max_steps=0` on a training launcher as a universal evaluation mode.** SFT interprets zero as no step cap. Math creates a remote session and does not provide a general eval-only CLI. For other RL tasks, compose `RLTestSetEvaluator` with the task's held-out builder and sampling client; for SFT, use `NLLEvaluator` on held-out data plus task-specific generation evaluation. These are programmatic APIs, not new documented CLI flags. @@ -241,8 +241,9 @@ No optimizer update occurs in this helper. It creates a `type="training"` sessio ### Print a real response from your saved state -After approving the new session and sampling operation, run this **after the -helper definition** in your private script. Replace the checkpoint placeholder +This creates a new paid session and samples from it. Warn before execution; +no separate spending approval is required. Run this **after the helper +definition** in your private script. Replace the checkpoint placeholder with the completed training `state_path`; do not invent a path from a failed save or a sampler-only identifier. This example matches the own-text walkthrough's model/renderer/rank and uses a new task prompt without supplying @@ -278,8 +279,8 @@ and inspect the new session's cleanup result separately. Passing `None` as the helper's checkpoint path creates a fresh baseline session without loading saved training state. The other arguments, prompt, -renderer, rank, and sampling parameters remain identical. After explicit -approval for **two session allocations and their sampling**, this example +renderer, rank, and sampling parameters remain identical. This example uses +**two paid session allocations and their sampling**; warn before running it. It checks one unseen synthetic label task; it is a comparison smoke test, not a quality benchmark or a statistical claim: @@ -301,7 +302,7 @@ async def compare_one_label(checkpoint_path): } return results -# Only after approving the new sessions/samples; keep responses private. +# Creates two paid sessions and samples from both; keep responses private. comparison = asyncio.run(compare_one_label("session_/final")) print(comparison) ``` @@ -326,7 +327,7 @@ The SDK operations above provide **sampling within Fine-Tuning Sessions**. They | Intended use | What this cookbook supplies | What must be confirmed separately | |---|---|---| -| Inspect a generated response | Compatible session restore, sampler sync, and SDK sampling above | Training/sampling approval, capacity, prompt privacy, and owned-session cleanup | +| Inspect a generated response | Compatible session restore, sampler sync, and SDK sampling above | Project access, capacity, prompt privacy, and owned-session cleanup | | Evaluate a task | Existing NER evaluation CLI, RL/SFT evaluator APIs, and the comparison contract | Task-specific generation/grading, complete coverage, and sufficient held-out evidence | | Run application inference | No documented permanent inference deployment in these helpers | A supported serving provider/path, compatible model/adapter format, serving access, auth/API contract, capacity, price, and deletion plan | | Export weights or run locally | No verified export/download/conversion recipe in the pinned public workflow | A supported export route, model/data/license rights, format compatibility, and separately validated conversion/runtime | diff --git a/interactive_training/docs/quickstart.md b/interactive_training/docs/quickstart.md index 3beae1a..9cf3ecc 100644 --- a/interactive_training/docs/quickstart.md +++ b/interactive_training/docs/quickstart.md @@ -11,7 +11,12 @@ Install the cookbook, perform local checks, run a bounded GSM8K workflow on Azur | Azure AI Foundry **project endpoint** in a supported region | [Resource and project setup](./auth.md#prerequisite--an-azure-ai-foundry-resource) | | Credentials authorized for this project | An API key, or an identity with the required project access; successful `az login` alone is not proof of authorization | | Eligibility and capacity for the selected model | [Supported models](./supported_models.md); availability depends on project region, capacity, and quota | -| Authorization to use paid compute | Training, evaluation, sampling, and model loading may incur charges; follow your project's spending controls | + +> [!WARNING] +> Training, evaluation, sampling, and model loading use paid cloud resources. +> When a user requests this workflow, warn once and proceed without a separate +> budget or spend-approval prompt. Include cost information if readily available; +> unknown pricing is not a blocker. No local GPU or local model-weight download is required for this text recipe. Keep the Python driver and its network connection alive until it finishes. Do not place sensitive data in a public run directory. @@ -121,7 +126,7 @@ If `AZURE_AI_API_KEY` is set, the math recipe uses that key instead. Otherwise i ## 6. Run the bounded remote workflow > [!WARNING] -> **This step creates a remote training session and may incur charges.** `max_steps=2` bounds training iterations, not model-loading time, evaluation calls, total generated tokens, or price. Run only with authorization to incur charges and follow your project's spending controls; this guide does not prescribe a maximum dollar amount. +> **This step creates a remote training session and may incur charges.** `max_steps=2` bounds training iterations, not model-loading time, evaluation calls, total generated tokens, or price. Respect any supplied spending limits; this guide does not require a dollar budget or a separate cost acknowledgement. The general text default is Qwen3.8 with low-effort thinking. Specify `max_tokens=1200`: the math launcher's five-token default is for its toy arithmetic configuration, not GSM8K reasoning. Reasoning and the final answer share the completion budget. @@ -148,8 +153,8 @@ This uses eight prompts with four completions per training iteration; validation The fixed run directory makes artifacts easy to find. `raise` deliberately refuses an existing directory: choose a new name for another independent run, or follow [recovery](./training.md#resuming-after-an-interruption) with the original config and `behavior_if_log_dir_exists=resume`. Do not use `delete` to resolve a recovery error. -No first-run duration or total price is promised. Before launching, agree on -an observation/stop plan with the owner and distinguish a session-creation +No first-run duration or total price is promised. Before launching, establish +the requested run's observation/stop plan and distinguish a session-creation timeout from cancellation. The CLI has a creation timeout and optional `max_wall_clock_seconds`, but a loop-boundary time limit is not a hard request, save, or billing cap. Inspect the last phase and owned session before retrying diff --git a/interactive_training/docs/recipes.md b/interactive_training/docs/recipes.md index 7c62744..d24e03d 100644 --- a/interactive_training/docs/recipes.md +++ b/interactive_training/docs/recipes.md @@ -17,7 +17,7 @@ A recipe is a small launcher that wires task-specific data and configuration int | Pairwise preferences | [preference/dpo](../interactive_training/recipes/preference/dpo/README.md) | Preference pairs and reference-session capacity | Held-out losses plus an independent task/preference evaluation | | Teacher imitation | [distillation](../interactive_training/recipes/distillation/README.md) | Compatible tokenization, teacher checkpoint, two sessions | Teacher/student difference plus independent quality evaluation | -All remote examples need project authorization, capacity, and budget. A CLI cap does not make a launch offline. Start with [installation/auth checks](./quickstart.md), adapt through [custom data](./custom-data.md), then follow [evaluation and inference](./evaluation-and-inference.md). +All remote examples need project authorization and capacity and may incur charges. Warn before a requested run without a separate spending-approval prompt. A CLI cap does not make a launch offline. Start with [installation/auth checks](./quickstart.md), adapt through [custom data](./custom-data.md), then follow [evaluation and inference](./evaluation-and-inference.md). ## Available recipes diff --git a/interactive_training/docs/session-management.md b/interactive_training/docs/session-management.md index 660d492..4acc214 100644 --- a/interactive_training/docs/session-management.md +++ b/interactive_training/docs/session-management.md @@ -186,9 +186,9 @@ For each candidate, confirm its owner/job is finished and required training save 4. Inspect the owned session using list/get and the management-operation result. If its release is uncertain, resolve that state with the administrator; do not treat a status label or `404` alone as a billing confirmation. -5. With explicit approval, unload only the identified leftover session after - saving needed state. Separate deletion requires separate confirmation - because it can remove checkpoints. Never sweep a shared project. +5. Within the requested run's cleanup plan, unload only the identified leftover + session after saving needed state. Separate deletion requires separate + confirmation because it can remove checkpoints. Never sweep a shared project. 6. Close local clients/credentials and approved sidecars. Separately provisioned serving deployments, VMs, tool sandboxes, and storage are not removed by session cleanup; report the remaining owners/resources and cost uncertainty. diff --git a/interactive_training/docs/storage.md b/interactive_training/docs/storage.md index 328df1e..6420478 100644 --- a/interactive_training/docs/storage.md +++ b/interactive_training/docs/storage.md @@ -107,7 +107,7 @@ successful process exit, to decide what to keep: | Prompt/response HTML, logs, `code.diff`, and notebook outputs | Failure analysis and task-error inspection | Review for private text, tokens, local paths, and unrelated code; retain only as policy permits and redact before sharing | | Completed remote training checkpoint | Compatible restart/recovery | Confirm save completion, intended owner/project, access, retention, and whether it is still the only recoverable state | | Remote sampler checkpoint | Sampling-format state for its supported session context | Keep its source session association; sampler-only state is not optimizer recovery or a deployment | -| Live session or separate serving resource | Only the approved active workload | Save required state, stop using it, and obtain approval for the specific unload/cancel/delete action; inspect the result | +| Live session or separate serving resource | Only the requested active workload | Save required state and follow the requested stop/cleanup plan for owned resources; obtain separate deletion confirmation and inspect the result | Unload and deletion are different operations. Do not delete the source session/checkpoints as a shortcut to releasing compute while you still need diff --git a/interactive_training/docs/training.md b/interactive_training/docs/training.md index 976a68f..26d509e 100644 --- a/interactive_training/docs/training.md +++ b/interactive_training/docs/training.md @@ -274,7 +274,7 @@ python -m interactive_training.recipes.math_rl.train_azure \ max_steps=2 ``` - This is a fragment to add to an approved, complete math command with endpoint, dataset, token budget, and run path; `...` is not a literal argument. It does not add `oversample_cushion` to the launcher. + This is a fragment to add to a complete math command within the requested run's scope, with endpoint, dataset, token budget, and run path; `...` is not a literal argument. It does not add `oversample_cushion` to the launcher. ### When to use it @@ -422,7 +422,7 @@ The directory must first be accepted with `behavior_if_log_dir_exists=resume` (o Keep the original model, tokenizer, renderer, and LoRA settings on resume. A new default model does not make older checkpoints compatible with a different base. -Also preserve dataset revision/order, split, seed, and batch/group configuration. The ledger is a cursor, not a complete snapshot of every in-flight async rollout or external tool state; do not promise bit-identical recovery. A run already at its `max_steps` cap will not continue past that cap unless you deliberately raise the approved budget. If there is no completed training checkpoint, unsaved optimizer work cannot be recovered from metrics or HTML. +Also preserve dataset revision/order, split, seed, and batch/group configuration. The ledger is a cursor, not a complete snapshot of every in-flight async rollout or external tool state; do not promise bit-identical recovery. A run already at its `max_steps` cap will not continue past that cap unless the requested scope includes raising that configured limit. If there is no completed training checkpoint, unsaved optimizer work cannot be recovered from metrics or HTML. > [!NOTE] > Resume creates a **new** Azure session initialized from the checkpoint — the new run reports its own `session_id` in `run_meta.json` and stamps `azure.from_checkpoint` with the source. The original session is not reattached. diff --git a/interactive_training/docs/troubleshooting.md b/interactive_training/docs/troubleshooting.md index 8bf6914..c4bae7b 100644 --- a/interactive_training/docs/troubleshooting.md +++ b/interactive_training/docs/troubleshooting.md @@ -80,7 +80,7 @@ If this happens, you can pick up from the last checkpoint — see [Resuming afte For anything beyond a quick smoke test (i.e. anything that runs longer than the time you're willing to babysit a terminal), launch the recipe from a **persistent, always-on machine** instead: -- **An approved always-on VM/container**, or Azure ML compute, with enough CPU/RAM/disk for the selected data and grader. The model GPUs are service-side, but code grading, retrieval, and large datasets can demand substantial driver resources. Provisioning requires separate approval/budget. +- **An approved always-on VM/container**, or Azure ML compute, with enough CPU/RAM/disk for the selected data and grader. The model GPUs are service-side, but code grading, retrieval, and large datasets can demand substantial driver resources. Provisioning must be explicitly requested; warn about costs without a separate spending-approval prompt. - Use Cloud Shell only for short administrative work when its runtime/storage/network constraints fit; it is not a guarantee of an unattended always-on training driver. - If you must use your laptop, at minimum keep it plugged in, disable sleep/hibernate (`caffeinate` on macOS, `systemd-inhibit` on Linux, or "never sleep when plugged in" in Windows power settings), and keep the lid open and the network connected. @@ -97,7 +97,7 @@ python -m pip install -e . --index-url https://pypi.org/simple --extra-index-url # launch under tmux/screen so the run survives SSH disconnects tmux new -s run -# Run the approved bounded command from docs/quickstart.md here. +# Run the requested bounded command from docs/quickstart.md here. # Ctrl-b d to detach; `tmux attach -t run` to come back ``` @@ -203,7 +203,7 @@ For builders that enforce the checks, shorten or split overlength examples, or r Read the last completed phase in the console/`logs.log`, then inspect the service request/error details and owned session. Cold model/sampler loading, checkpoint serialization, queueing, and grading can take time; no universal first-step duration is promised. A submitted request or warning is not completion. Keep the driver alive and do not submit duplicate paid runs just because no metric row appeared yet. -If a request is terminally failed, preserve its error code/request ID and follow the service's retry guidance. For GPU/memory errors, verify the actual model/rank/context/group/batch configuration and checkpoint/sampler operation involved; do not reinterpret a sampler allocation as a cheap disk-only save. Reduce only the relevant approved workload for a subsequent run, or escalate with sanitized evidence. Resume from a completed **training** checkpoint when available; unsaved state cannot be reconstructed from logs. +If a request is terminally failed, preserve its error code/request ID and follow the service's retry guidance. For GPU/memory errors, verify the actual model/rank/context/group/batch configuration and checkpoint/sampler operation involved; do not reinterpret a sampler allocation as a cheap disk-only save. Reduce only the relevant workload within the requested scope for a subsequent run, or escalate with sanitized evidence. Resume from a completed **training** checkpoint when available; unsaved state cannot be reconstructed from logs. ## Answers truncate or quality does not improve diff --git a/interactive_training/interactive_training/recipes/tool_rl/README.md b/interactive_training/interactive_training/recipes/tool_rl/README.md index d2139dc..13cc922 100644 --- a/interactive_training/interactive_training/recipes/tool_rl/README.md +++ b/interactive_training/interactive_training/recipes/tool_rl/README.md @@ -143,8 +143,8 @@ For an independent BFCL evaluation, follow the in a separate evaluation environment and verify that its model-access interface supports your intended setup. A cookbook checkpoint identifier is not a local weights export that the BFCL CLI can load directly; this recipe supplies no -export or serving adapter. Obtain approval and budget before any evaluation -that invokes paid inference. +export or serving adapter. Warn before an evaluation that invokes paid +inference; no separate spending approval or dollar budget is required. The xLAM holdout `bfcl_strict` metric here is internally consistent for tracking training progress but uses the same data distribution as training — it does not diff --git a/managed_fine_tuning/03-core-rft/01-rft-countdown/CANCELLATION_AND_CLEANUP.md b/managed_fine_tuning/03-core-rft/01-rft-countdown/CANCELLATION_AND_CLEANUP.md index 76ae992..f551963 100644 --- a/managed_fine_tuning/03-core-rft/01-rft-countdown/CANCELLATION_AND_CLEANUP.md +++ b/managed_fine_tuning/03-core-rft/01-rft-countdown/CANCELLATION_AND_CLEANUP.md @@ -6,9 +6,10 @@ use a different state format and cannot be used unchanged here. ## Before requesting cancellation Closing the notebook or timing out monitoring does **not** cancel training. -Cancellation loses progress and does not undo accrued charges. Obtain approval -for the specific project and job, including remaining cost uncertainty. Check -Foundry for jobs missing from local state after an ambiguous submission. +Cancellation loses progress and does not undo accrued charges. Cancel only an +identified owned job within the requested stop/cleanup plan or an explicit +cancellation request; no separate spending approval is required. Check Foundry +for jobs missing from local state after an ambiguous submission. From the Countdown demo directory, review the ignored `outputs/submission-state.json` privately. Its `jobs` map holds `model-grader` @@ -17,9 +18,9 @@ the project independently in Foundry; an optional `job_endpoints` entry in older state is checked but is **not** sufficient proof on its own. Do not retroactively fill it from `.env`, or share populated state or credentials. -With the managed environment installed, run this snippet **once** after -approval. It retrieves and confirms **one** selected job before requesting -cancellation; it does not cancel both jobs: +With the managed environment installed, run this snippet **once** for the +requested cancellation. It retrieves and confirms **one** selected job before +requesting cancellation; it does not cancel both jobs: ```python import json diff --git a/managed_fine_tuning/GETTING_STARTED.md b/managed_fine_tuning/GETTING_STARTED.md index f0523f9..ae02662 100644 --- a/managed_fine_tuning/GETTING_STARTED.md +++ b/managed_fine_tuning/GETTING_STARTED.md @@ -72,6 +72,11 @@ running its inference comparison cells. ## Before a paid or long-running operation +Warn that the requested workflow uses paid cloud resources, then proceed without +a separate spend-approval prompt. Include cost information if readily available; +unknown pricing or a missing dollar budget is not a blocker. Follow the +[execution contract](../AGENTS.md#paid-execution-warn-then-proceed). + 1. Validate the exact runtime-generated or preserved JSONL files with `validate_jsonl(...).require_valid()`. 2. Verify train/validation/test isolation with `validate_split_isolation(...)`.