AWS Bedrock model customization spans four distinct mechanisms — supervised fine-tuning (SFT), continued pre-training (CPT), model distillation, and reinforcement fine-tuning (RFT) — each with different billing models, CUR signatures, and FinOps implications. The decision between these and alternatives like RAG or prompt engineering is primarily economic: training is a one-time capital cost; inference is recurring operating cost. Getting the break-even math wrong by even one order of magnitude is the single most common source of customization project overruns.
This note covers the full cost stack: training, storage, inference deployment, observability overhead, and amortization.
1. Bedrock Fine-Tuning Pricing by Model
1.1 Per-Token Training Costs
Fine-tuning and continued pre-training are billed on total tokens processed, which equals dataset_tokens × epoch_count. The table below reflects current AWS pricing as of June 2026.
| Model Family | Model | Training Cost per 1K Tokens | Notes |
|---|---|---|---|
| Amazon Titan | Titan Text Lite | $0.00100 | Smallest, fastest to converge |
| Amazon Titan | Titan Text Express | $0.00800 | Mid-tier; most common for enterprise SFT |
| Meta Llama | Llama 2 13B | $0.00149 | Legacy; prefer Llama 3 via CMI |
| Meta Llama | Llama 2 70B | $0.00799 | ~$8/M tokens; requires large dataset to justify |
| Cohere | Command | $0.00400 | Solid RAG + instruction tuning baseline |
| Amazon Nova | Nova Micro/Lite/Pro | On-demand rate (varies) | See §1.2 — SFT billed at standard token rate |
Nova SFT pricing anomaly. Amazon Nova custom models are billed at the same on-demand inference rate as base models — there is no training surcharge listed as a separate SKU. In practice, the training compute is embedded in the job duration. A Nova Micro SFT run on ~1.75M tokens (4,978 examples × 3 epochs) completed in ~1.5 hours and cost $2.18. This implies an effective training rate of approximately $1.25/M tokens for Nova Micro, well below Llama 2 70B.
Reinforcement Fine-Tuning (RFT). RFT on Bedrock is billed hourly, not per token. Current rates:
| Model | RFT Hourly Rate |
|---|---|
| OpenAI gpt-oss-20b | $80.00/hr |
| Qwen3 32B | $80.00/hr |
| Amazon Nova 2 Lite | Not published; billed per token at customization rate |
RFT jobs are typically 2–8 hours for a few thousand prompts. A 4-hour gpt-oss-20b RFT run costs $320 in compute before storage or inference. For Nova RFT, the token-based billing means costs scale linearly with dataset size and trainingSamplePerPrompt (default 4), which multiplies effective token consumption by that factor.
1.2 Storage Costs
Every custom model — SFT, CPT, distilled, or RFT — incurs a flat monthly storage fee:
- $1.95 per model per month (standard; applies per Custom Model Unit for CMI)
- For Custom Model Import: $1.95 per CMU per month
Storing 10 fine-tuned model versions costs $19.50/month. At scale, version proliferation becomes a non-trivial line item. See §8 on version governance.
1.3 GPU-Hour Charges
Bedrock abstracts GPU scheduling; customers do not choose instance types. The per-token rates subsume GPU cost. The exception is RFT (hourly billing) and, implicitly, Custom Model Import, which exposes compute via Custom Model Units (CMUs). One CMU maps to a discrete amount of GPU VRAM. A Llama 3.1 8B model with 128K context requires 2 CMUs; at $0.05718/CMU/minute in us-east-1, a single active copy costs $0.11436/minute or $6.86/hour.
2. How Fine-Tuning Costs Appear in CUR
2.1 CUR 2.0 Architecture
Bedrock billing uses CUR 2.0 (AWS Data Exports). The line_item_usage_type field encodes model, token type, service tier, and routing in a structured pattern:
{region}-{model}-{token-type} # standard tier, in-region
{region}-{model}-{token-type}-{tier} # priority or flex tier
{region}-{model}-mantle-{token-type}-standard # bedrock-mantle endpoint
{region}-{model}-{token-type}-cross-region-global # cross-region routing
Example inference line items:
| usage_type | Model | Service Tier | Token Type |
|---|---|---|---|
USE1-Claude4.6Sonnet-input-tokens |
Claude Sonnet 4.6 | Standard | Input |
USE1-Nova2.0Lite-input-tokens-flex |
Amazon Nova 2 Lite | Flex | Input |
USE1-Claude4.6Sonnet-cache-read-input-token-count |
Claude Sonnet 4.6 | Standard | Cache Read |
2.2 Training Job Line Items
Fine-tuning training jobs appear under the bedrock service with a distinct line_item_operation value. Based on AWS documentation and community observation:
- Operation column:
CreateModelCustomizationJoborModelCustomization - Usage type pattern:
{region}-{model}-customization-tokensor{region}-ModelCustomization - Resource ID: The ARN of the customization job
For RFT (hourly billing models), the operation is ReinforcementFineTuning and the usage type reflects compute-hours rather than tokens.
Critical reconciliation gap: CUR aggregates by usage type per hour or per day — it does not emit per-job line items. To reconcile a training job’s cost, you must join CUR on the job’s start/end timestamps and sum line_item_unblended_cost over that window for the model’s customization usage type.
2.3 Custom Model Import Line Items
CMI inference billing appears as:
- Service:
AmazonBedrock - Usage type:
{region}-CustomModelImport-CMU-Minutes(inferred from pricing model) - Operation:
InvokeModelorInvokeModelWithResponseStream - Billing granularity: 5-minute windows, even for sub-minute invocations
Idle CMI cost — a model copy loaded but not receiving traffic — is the primary cost leak. An idle 2-CMU model costs $6.86/hour. AWS added real-time cost transparency to CMI in March 2025, surfacing estimated CMU-minute charges in the Bedrock console before invocation.
2.4 Four Token Types — All Must Be Captured
A frequent CUR reconciliation error is summing only input and output tokens. Bedrock charges four distinct token types:
| Token Type | CUR Pattern | Relative Cost |
|---|---|---|
| Input | *-input-tokens |
Baseline |
| Output | *-output-tokens |
3–5× input rate |
| Cache Read | *-cache-read-input-token-count |
~10% of input rate |
| Cache Write | *-cache-write-input-token-count |
~125% of input rate |
Workloads using prompt caching heavily will show reconciliation gaps of 15–30% if cache tokens are excluded from cost rollups.
3. Continued Pre-Training vs Fine-Tuning vs Distillation
3.1 Method Comparison
| Dimension | Continued Pre-Training (CPT) | Supervised Fine-Tuning (SFT) | Model Distillation | Reinforcement Fine-Tuning (RFT) |
|---|---|---|---|---|
| Data format | Raw unlabeled text | Input/output pairs | Teacher-generated completions | Prompts + reward function |
| Primary use | Domain vocabulary injection | Task format adaptation | Capability compression | Reasoning/alignment tuning |
| Token cost | Lowest (no labels needed) | Medium | Teacher inference + student training | Highest (GRPO sampling ×N) |
| Dataset scale | Billions of tokens | Thousands to millions | Tens of thousands | Hundreds to thousands |
| Billing model | Per token | Per token | Teacher on-demand rate + student customization | Per GPU-hour (some models) or per token |
| Quality ceiling | Adds knowledge; no behavioral change | Strong task-specific gains | Matches teacher on target tasks ± 2–3% | Best for objective verifiable tasks |
3.2 Distillation Cost Model
Model distillation has two cost stages:
-
Synthetic data generation (teacher model, on-demand rates): Nova Premier or Claude 3.5 Sonnet v2 generates completions for your prompt set. At $0.024/1K output tokens for Nova Premier, generating 50K examples of 500 tokens each costs $600.
-
Student model training (customization rate): Training a Nova Micro student on those 50K examples × 3 epochs = 150M × student_token_rate ≈ $188 at $1.25/M effective rate.
Total distillation cost: ~$788 for 50K examples versus $188 for SFT alone. The premium pays for higher quality training signal. Reported quality: <2% accuracy loss on target tasks, up to 75% inference cost reduction, and ~5× throughput improvement by moving from a large teacher to a small distilled model.
Distillation paths available as of 2026:
- Nova Premier → Nova Pro
- Claude 3.5 Sonnet v2 → Llama 3.2 1B / 3B
3.3 When Each Method Is Economical
| Use Case | Recommended Approach | Rationale |
|---|---|---|
| Domain jargon (medical, legal, financial) the model misrecognizes | CPT | Cheapest; no labeled data required |
| Consistent output format (JSON schema, structured reports) | SFT | High ROI per labeled example |
| Production cost reduction while maintaining quality | Distillation | 75% inference savings at modest upfront cost |
| Math/code/logic tasks with verifiable outputs | RFT | Verifiable reward functions; measurable gain |
| Low-volume, infrequent tasks | None (prompt engineer + RAG) | Provisioned throughput overhead kills ROI |
4. Custom Model Import (CMI) Billing
4.1 CMI Architecture
CMI imports externally trained or LoRA-adapted models (Llama, Mistral, Falcon families) into Bedrock’s managed inference plane. There is no import fee; billing applies only when inference copies are active.
Billing mechanics:
- Unit: Custom Model Unit (CMU) — a fixed amount of GPU VRAM
- Rate: $0.05718 per CMU per minute (us-east-1)
- Billing window: 5-minute minimum, regardless of actual traffic
- Europe (Frankfurt): $0.07144/CMU/minute (~25% premium)
- OpenAI custom models via CMI: $0.1433/CMU/minute (~2.5× standard)
4.2 CMU Requirements by Model Size
AWS determines CMU count automatically based on model architecture, context length, and quantization. Observed baselines:
| Model | Context | CMUs Required | Cost/Minute (us-east-1) | Cost/Hour |
|---|---|---|---|---|
| Llama 3.1 8B | 128K | 2 | $0.11436 | $6.86 |
| Llama 3.1 70B | 128K | ~8 | ~$0.457 | ~$27.43 |
| Llama 3.1 405B | 128K | ~32 | ~$1.829 | ~$109.74 |
| Custom LoRA adapter on 8B | 128K | 2 (same as base) | $0.11436 | $6.86 |
LoRA adapters do not reduce CMU requirements because the inference server loads the merged weights. CMI billing reflects base model size, not adapter size.
4.3 Idle Cost — The Primary CMI Leak
A CMI model copy loaded and waiting costs identically to one serving traffic. The minimum active window is 5 minutes, meaning a single invocation to a cold CMI model costs at least $0.11436 × 2 CMU × 1 window = $0.229 for the cold-start billing window alone.
For low-traffic use cases, CMI is economically dominated by Provisioned Throughput (PT) only when traffic volume exceeds the PT commitment floor. The inflection point:
CMI_monthly_cost = CMU_count × $0.05718/min × active_minutes/month
PT_monthly_cost = model_units × PT_hourly_rate × 730 hours/month
CMI wins when: active_minutes/month < (PT_units × PT_rate × 730) / (CMU × 0.05718)
For a 2-CMU model vs. 1-MU Provisioned Throughput at $21.18/hour (Llama 2 13B 1-month commitment):
- PT monthly: $21.18 × 730 = $15,461
- CMI break-even: $15,461 / ($0.11436/min) = 135,225 active minutes/month = ~2,254 hours/month
At fewer than ~2,254 active hours per month (93% utilization), CMI is cheaper than the 1-month PT commitment. CMI is almost always the right default unless traffic is continuous.
4.4 CMI vs Provisioned Throughput Decision Matrix
| Signal | Use CMI | Use Provisioned Throughput |
|---|---|---|
| Traffic pattern | Spiky, bursty | Flat, predictable |
| Utilization | <80% | >85% sustained |
| Model commitment | None required | 1-month or 6-month |
| LoRA/quantized weights | Yes (CMI native) | No (PT requires Bedrock-native models) |
| Cost attribution | CMU-minute granularity | Hourly lump sum |
5. Break-Even Analysis: Fine-Tuning vs Prompt Engineering vs RAG
5.1 The Three-Strategy Cost Model
Strategy A: Prompt Engineering Only
Cost = inference_calls/month × avg_tokens/call × on_demand_rate
For Claude Sonnet 4.6 ($3/$15 per 1M in/out) with a 2K-token system prompt + 500-token user input + 300-token output:
Monthly tokens = calls × (2500 input + 300 output)
Monthly cost = calls × (2500 × $0.003/1K + 300 × $0.015/1K)
= calls × ($0.0075 + $0.0045)
= calls × $0.012
At 100K calls/month: $1,200/month. The 2K system prompt is the primary cost driver — it is repeated on every call.
Strategy B: RAG (Bedrock Knowledge Bases)
Cost = retrieval_queries × $0.01 + inference_cost_with_shorter_context + Knowledge_Base_storage
RAG reduces prompt length by replacing the full context window with retrieved chunks (typically 3–5 × 500-token chunks = 1,500 tokens vs. a 2K static prompt). Net token savings: ~500 tokens/call in this example.
Savings at 100K calls: 500 × 100K × $0.003/1K = $150/month in token savings RAG query cost: 100K × $0.01 = $1,000/month Knowledge Base overhead via OpenSearch Serverless: minimum ~$700/month (4 OCUs at $0.24/OCU-hour × 730)
RAG net cost at 100K calls/month: ($1,200 - $150) + $1,000 + $700 = $2,750/month. RAG is more expensive than pure prompting at this volume, unless retrieval replaces a much larger context window (>5K tokens).
Note: Amazon S3 Vectors (GA December 2025) reduces Knowledge Base backend cost by ~90% vs OpenSearch Serverless. At $70/month storage floor, RAG economics improve substantially for new deployments.
Strategy C: Fine-Tuned Model on CMI
One-time training cost + monthly (storage + inference)
Training: dataset_tokens × epochs × training_rate
e.g., 10M tokens × 3 epochs = 30M × $0.004/1K = $120
Storage: $1.95/month
Inference: calls × shorter_avg_tokens × rate
(SFT bakes context into weights → shorter prompts)
e.g., 500-token average (system prompt eliminated)
100K calls × 500 tokens × $0.003/1K = $150/month
CMI inference for a Llama 3.1 8B fine-tuned model at 100K calls/month (assuming 10 calls/minute peak, 8 active hours/day):
Active minutes/month = 8 hrs × 60 min × 22 days = 10,560 min
CMI cost = 10,560 min × 2 CMU × $0.05718 = $1,207/month
Fine-tuned model total: $120 (amortized over 12 months = $10) + $1.95 + $1,207 = $1,219/month
5.2 Break-Even Table
| Monthly Call Volume | Prompt Engineering | RAG (S3 Vectors) | Fine-Tuned (CMI 8B) | Winner |
|---|---|---|---|---|
| 10K | $120 | $270 | $185 | Prompt Engineering |
| 50K | $600 | $670 | $650 | Prompt Engineering |
| 100K | $1,200 | $870 | $1,219 | RAG |
| 500K | $6,000 | $3,550 | $3,800 | RAG |
| 1M | $12,000 | $6,600 | $5,500 | Fine-Tuned |
| 5M | $60,000 | $31,500 | $18,000 | Fine-Tuned |
Assumptions: Claude Sonnet 4.6 base; 2K system prompt replaced by SFT; 3 retrieved chunks at 500 tokens each; CMI 8B at 2 CMUs; 40% active hours/month for CMI; S3 Vectors backend at $70/month fixed.
The key threshold: fine-tuning becomes economically favorable above ~750K calls/month when a substantial system prompt can be eliminated through model weight encoding. Below that threshold, RAG with S3 Vectors is the dominant strategy.
5.3 When Fine-Tuning Clears the Bar Regardless of Volume
Volume thresholds are not the only decision criterion. Fine-tuning is mandatory when:
- Latency is the constraint. SFT on a small model (Nova Micro) may be the only way to hit <200ms p95 while maintaining quality. RAG adds retrieval latency; long prompts add prefill latency.
- The base model fails the task structurally. Some output formats (domain-specific structured schemas, specialized code dialects) are not achievable via prompting alone.
- Data cannot leave the context window for compliance reasons. SFT can encode regulatory or legal knowledge into weights, avoiding retrieval of sensitive reference material at inference time.
- The model is used as a tool-use router. SFT for function-calling classification can reduce routing errors below the prompt engineering baseline at any volume.
6. Model Evaluation Costs for Fine-Tuned Models
6.1 Bedrock Model Evaluation Pricing
Bedrock Model Evaluation supports two evaluation modes:
| Mode | Cost | Notes |
|---|---|---|
| Automatic (algorithmic) | Free | Uses built-in metrics; no human review |
| Human-based (via Mechanical Turk or private workforce) | $0.21 per completed task | Plus inference costs for generating model outputs |
For a standard evaluation setup (50 prompts, 2 human workers per prompt):
Human tasks: 50 prompts × 2 workers × $0.21 = $21.00
Inference cost: 50 prompts × avg_tokens × model_rate
e.g., 50 × 1,000 tokens × $0.003/1K = $0.15
Total evaluation: ~$21.15
At 1,000 prompts with 2 workers: $420 in human evaluation fees + inference costs.
6.2 Evaluation Cadence and Amortization
A typical fine-tuning workflow involves:
- Initial evaluation: Full benchmark suite after first training run
- Regression evaluation: Subset (200–500 prompts) after each data update
- Production monitoring: Continuous sample (1–5% of live traffic) with algorithmic scoring
For monthly regression evaluations at 500 prompts, 2 workers: $210/month in human evaluation overhead. This is often overlooked in TCO models and can add 10–20% to the cost of maintaining a fine-tuned model in production.
7. Multi-Turn Fine-Tuning Dataset Costs
7.1 S3 Storage for Training Data
Training datasets for Bedrock SFT are stored in S3 in JSONL format (one example per line). Storage costs are negligible at typical dataset sizes:
Dataset size estimate:
10K examples × avg 2,000 tokens × 4 bytes/token ≈ 80 MB
100K examples ≈ 800 MB
1M examples ≈ 8 GB
S3 Standard cost: $0.023/GB/month
10K examples: ~$0.002/month
1M examples: ~$0.184/month
S3 storage is not a meaningful cost line for training data. It becomes relevant only for distillation workflows where large teacher-generated synthetic datasets are retained across multiple training runs.
7.2 Data Preprocessing Lambda Costs
For automated data pipeline workflows (cleaning, formatting, validation), Lambda charges apply:
Lambda cost model:
Duration: $0.0000166667 per GB-second
Requests: $0.20 per 1M requests
Typical preprocessing job (1M examples):
Duration: 10 min × 2 GB memory = 1,200 GB-seconds = $0.02
Requests: minimal
Data validation pass: <$0.10 per million examples
Lambda preprocessing is negligible. The real preprocessing cost is human time for data curation. For labeled SFT datasets, data labeling via Amazon SageMaker Ground Truth or Mechanical Turk typically runs $0.01–$0.50 per labeled example depending on complexity. 10K high-quality labeled examples from human annotators may cost $5,000–$50,000 — dwarfing all AWS compute costs for the training job itself.
7.3 Multi-Turn Conversation Format
Bedrock SFT and RFT both accept the OpenAI Chat Completions format (JSONL with messages arrays). Multi-turn examples are priced identically to single-turn — total tokens across all turns count toward the training token total. A 5-turn conversation averaging 300 tokens per turn (1,500 tokens total) costs:
1,500 tokens × $0.004/1K (Cohere Command rate) = $0.006 per example
For 10K multi-turn examples: $60 training cost. Data preparation is the dominant cost.
8. Versioning and Rollback Costs
8.1 Storage Cost Scaling
Each saved model version costs $1.95/month. There is no differential versioning (delta storage) — each model version is stored as full weights. Version proliferation is therefore a linear cost:
| Active Versions | Monthly Storage Cost |
|---|---|
| 1 | $1.95 |
| 5 | $9.75 |
| 10 | $19.50 |
| 20 | $39.00 |
| 50 | $97.50 |
At typical enterprise deployment cadences (weekly retraining for 12 months = 52 versions), storage reaches $101.40/month. Version retention policy is the primary governance lever.
8.2 Rollback Cost Implications
Rolling back to a prior fine-tuned model version requires no re-training cost — the version is already stored. However, if the rollback version is served via CMI, it must be loaded into a new CMU allocation (billing starts on load). For Provisioned Throughput, switching to a prior version requires creating a new PT commitment (minimum 1-month).
Recommended pattern: Maintain at most 3 active versions: current production, prior production (immediate rollback target), and staging (next candidate). Archive older versions to S3 directly (model weights exported) and delete from Bedrock to avoid storage fees. Re-import via CMI if needed.
8.3 Version Tagging for CUR Attribution
Tag each model version in Bedrock with cost allocation tags at creation:
bedrock.create_model_customization_job(
...
customModelTags=[
{"key": "model-version", "value": "v4"},
{"key": "team", "value": "fraud-detection"},
{"key": "cost-center", "value": "CC-1234"},
]
)
Tags flow to CUR under resourceTags/model-version, enabling per-version cost queries without manual timestamp correlation.
9. LoRA/QLoRA via CMI vs Full Fine-Tuning on Bedrock
9.1 Mechanism Differences
| Dimension | Full Fine-Tuning (Bedrock Native) | LoRA/QLoRA via CMI |
|---|---|---|
| Weight update scope | All parameters | Low-rank adapter matrices only (~0.1–1% of params) |
| Training infrastructure | AWS-managed | Customer-managed (SageMaker, EC2, local) |
| Training cost location | Bedrock API (per token) | SageMaker/EC2 GPU hours |
| Model import cost | N/A | Free (no import fee) |
| Inference CMU requirement | Provisioned Throughput | CMI: same CMU as base model |
| Quality vs full fine-tuning | Reference baseline | 90–95% task quality retention |
| Memory efficiency | N/A | 10–20× reduction during training |
9.2 LoRA Training Cost (Self-Managed)
LoRA training on SageMaker for a Llama 3.1 8B model:
Instance: ml.g5.2xlarge (1× A10G 24GB) @ $1.515/hour
Duration: ~2 hours for 10K examples, 3 epochs
Total: $3.03 for training compute
vs. Bedrock native SFT on Llama 2 70B:
10K examples × avg 500 tokens × 3 epochs = 15M tokens
15M × $0.00799/1K = $119.85
For smaller models, LoRA + CMI is 40× cheaper to train than Bedrock native SFT on comparable parameter-count models. The tradeoff is operational complexity: managing SageMaker training pipelines, model merging, and CMI import workflows.
9.3 QLoRA Memory-Cost Tradeoff
QLoRA (4-bit quantization during training) reduces GPU memory 33% vs full-precision LoRA. Trade-off: 39% longer training duration, which increases SageMaker instance-hours proportionally.
LoRA training: 2 hours × $1.515 = $3.03
QLoRA training: 2.78 hours × $1.515 = $4.21 (39% longer)
QLoRA savings: Can use ml.g5.xlarge (1× A10G 24GB) instead of larger instance
Enables 13B–34B models on single-GPU hardware
For models up to 13B parameters, QLoRA on a single ml.g5.2xlarge is the cost-optimal training path. Above 34B parameters, full Bedrock SFT or multi-GPU LoRA becomes more practical unless the team has GPU cluster access.
9.4 CMI Inference for LoRA Adapters
Once a LoRA adapter is merged into base model weights and imported via CMI, inference billing is identical to any other CMI model — per CMU per minute. There is no LoRA-specific discount or surcharge. The primary inference advantage is smaller model footprint if a distilled or smaller base was used.
10. LiteLLM Routing for Fine-Tuned Models: A/B Testing Cost Attribution
10.1 LiteLLM + Bedrock Setup
LiteLLM proxies Bedrock custom models using the model ARN or custom endpoint alias:
import litellm
# Base model
response_base = litellm.completion(
model="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
messages=[{"role": "user", "content": prompt}]
)
# Fine-tuned model via CMI
response_ft = litellm.completion(
model="bedrock/arn:aws:bedrock:us-east-1:123456789012:imported-model/my-ft-model",
messages=[{"role": "user", "content": prompt}]
)
LiteLLM’s spend tracking records input_tokens, output_tokens, and cost per request using registered model rates. For CMI models, the per-token cost is not intrinsically known to LiteLLM — it must be configured via a custom pricing override, because CMI billing is per CMU-minute (capacity-based), not per token (consumption-based).
10.2 A/B Testing Cost Attribution Pattern
For controlled fine-tuned vs. base model comparison:
# litellm_config.yaml
model_list:
- model_name: "inference-router"
litellm_params:
model: "bedrock/claude-sonnet-4-6"
weight: 90 # 90% traffic to base
- model_name: "inference-router"
litellm_params:
model: "bedrock/arn:aws:bedrock:us-east-1:123456789012:imported-model/ft-v4"
weight: 10 # 10% traffic to fine-tuned
router_settings:
routing_strategy: "weighted-pick"
# Add metadata tags for cost attribution
metadata:
variant: "ft-v4"
experiment_id: "exp-fraud-2026-06"
LiteLLM logs are emitted to your observability backend (Langfuse, Heliconia, CloudWatch) with the metadata tags. Query by variant to compare:
- Token consumption per request (base vs. fine-tuned — expect shorter output if SFT improved format compliance)
- Cost per request (LiteLLM estimate for base; CMU-minute allocation for fine-tuned must be computed externally)
- Latency distribution (fine-tuned smaller model typically shows lower p50 and p99)
Critical gap: LiteLLM cannot accurately estimate CMI cost in real time because CMI charges are capacity-based (CMU-minutes), not consumption-based (tokens). The correct approach is to log all CMI invocations with timestamps, then join against CloudWatch CMU-minute metrics or CUR line items to compute actual cost per call post-hoc.
10.3 Bedrock Application Inference Profiles for A/B Attribution
For production-grade A/B attribution without LiteLLM overhead, create separate Application Inference Profiles (AIPs) per variant:
bedrock.create_inference_profile(
inferenceProfileName="ft-v4-fraud-detection",
description="Fine-tuned Llama 8B for fraud classification - v4",
modelSource={
"copyFrom": "arn:aws:bedrock:us-east-1:123456789012:imported-model/ft-v4"
},
tags=[
{"key": "variant", "value": "ft-v4"},
{"key": "experiment", "value": "fraud-2026-06"},
]
)
Use the profile ARN in your inference calls. Profile tags flow to CUR resourceTags/variant and resourceTags/experiment, enabling direct Cost Explorer filtering by variant. No LiteLLM proxy required.
11. CUR Athena Queries for Fine-Tuned Model TCO
11.1 Schema Assumptions
Queries assume CUR 2.0 exported to S3 and crawled by Glue. Table name: cur_database.bedrock_costs. Partitioned by year and month.
11.2 Query 1: Training Job Cost Isolation
-- Isolate all model customization spend by job name
SELECT
line_item_resource_id AS job_arn,
resource_tags_model_version AS model_version,
resource_tags_team AS team,
SUM(line_item_unblended_cost) AS training_cost_usd,
SUM(line_item_usage_amount) AS total_tokens_thousands,
MIN(line_item_usage_start_date) AS job_start,
MAX(line_item_usage_end_date) AS job_end
FROM cur_database.bedrock_costs
WHERE year = '2026'
AND month IN ('05', '06')
AND line_item_product_code = 'AmazonBedrock'
AND line_item_operation LIKE '%ModelCustomization%'
GROUP BY 1, 2, 3
ORDER BY training_cost_usd DESC;
11.3 Query 2: Inference Cost by Model Variant (AIP tags)
-- Compare inference cost per 1K requests: base vs fine-tuned variant
SELECT
resource_tags_variant AS model_variant,
resource_tags_experiment AS experiment,
COUNT(*) AS billing_records,
SUM(line_item_usage_amount) AS total_tokens,
SUM(line_item_unblended_cost) AS inference_cost_usd,
SUM(line_item_unblended_cost)
/ NULLIF(SUM(line_item_usage_amount), 0) * 1000000 AS cost_per_million_tokens
FROM cur_database.bedrock_costs
WHERE year = '2026'
AND month = '06'
AND line_item_product_code = 'AmazonBedrock'
AND line_item_operation IN ('InvokeModel', 'InvokeModelWithResponseStream')
AND resource_tags_experiment IS NOT NULL
GROUP BY 1, 2
ORDER BY model_variant, experiment;
11.4 Query 3: CMI Capacity Cost (CMU-Minutes)
-- Track Custom Model Import capacity spend by imported model
SELECT
line_item_resource_id AS model_arn,
resource_tags_model_version AS version,
SUM(line_item_usage_amount) AS total_cmu_minutes,
SUM(line_item_unblended_cost) AS cmu_cost_usd,
SUM(line_item_unblended_cost) / 730.0 AS avg_hourly_cmu_cost
FROM cur_database.bedrock_costs
WHERE year = '2026'
AND month = '06'
AND line_item_product_code = 'AmazonBedrock'
AND line_item_usage_type LIKE '%CustomModelImport%'
GROUP BY 1, 2
ORDER BY cmu_cost_usd DESC;
11.5 Query 4: Amortized TCO — Training + Inference Over Model Lifetime
-- Full TCO: amortize training cost over N months, add ongoing inference + storage
WITH training_costs AS (
SELECT
resource_tags_model_version AS model_version,
SUM(line_item_unblended_cost) AS training_cost_usd
FROM cur_database.bedrock_costs
WHERE line_item_operation LIKE '%ModelCustomization%'
AND resource_tags_model_version IS NOT NULL
GROUP BY 1
),
monthly_inference AS (
SELECT
resource_tags_model_version AS model_version,
DATE_FORMAT(line_item_usage_start_date, '%Y-%m') AS billing_month,
SUM(line_item_unblended_cost) AS monthly_inference_usd
FROM cur_database.bedrock_costs
WHERE line_item_operation IN ('InvokeModel', 'InvokeModelWithResponseStream',
'InvokeModelInference')
AND resource_tags_model_version IS NOT NULL
GROUP BY 1, 2
),
monthly_storage AS (
SELECT
resource_tags_model_version AS model_version,
DATE_FORMAT(line_item_usage_start_date, '%Y-%m') AS billing_month,
SUM(line_item_unblended_cost) AS monthly_storage_usd
FROM cur_database.bedrock_costs
WHERE line_item_usage_type LIKE '%ModelStorage%'
AND resource_tags_model_version IS NOT NULL
GROUP BY 1, 2
),
months_active AS (
SELECT model_version, COUNT(DISTINCT billing_month) AS months
FROM monthly_inference GROUP BY 1
)
SELECT
i.model_version,
t.training_cost_usd,
m.months AS months_active,
t.training_cost_usd / NULLIF(m.months, 0) AS amortized_training_per_month,
AVG(i.monthly_inference_usd) AS avg_monthly_inference,
AVG(s.monthly_storage_usd) AS avg_monthly_storage,
(t.training_cost_usd / NULLIF(m.months, 0))
+ AVG(i.monthly_inference_usd)
+ AVG(s.monthly_storage_usd) AS amortized_monthly_tco
FROM training_costs t
JOIN months_active m ON t.model_version = m.model_version
LEFT JOIN monthly_inference i ON t.model_version = i.model_version
LEFT JOIN monthly_storage s
ON t.model_version = s.model_version
AND i.billing_month = s.billing_month
GROUP BY 1, 2, 3, 4
ORDER BY amortized_monthly_tco DESC;
11.6 Query 5: Cache Token Reconciliation (Prevent Undercounting)
-- All four token types must be included for accurate Bedrock cost reconciliation
SELECT
resource_tags_team AS team,
SUM(CASE WHEN line_item_usage_type LIKE '%-input-tokens'
THEN line_item_unblended_cost ELSE 0 END) AS input_cost,
SUM(CASE WHEN line_item_usage_type LIKE '%-output-tokens'
THEN line_item_unblended_cost ELSE 0 END) AS output_cost,
SUM(CASE WHEN line_item_usage_type LIKE '%-cache-read-%'
THEN line_item_unblended_cost ELSE 0 END) AS cache_read_cost,
SUM(CASE WHEN line_item_usage_type LIKE '%-cache-write-%'
THEN line_item_unblended_cost ELSE 0 END) AS cache_write_cost,
SUM(line_item_unblended_cost) AS total_cost,
-- Reconciliation check: unexplained cost not matching any of the four types
SUM(CASE WHEN line_item_usage_type NOT LIKE '%-input-tokens'
AND line_item_usage_type NOT LIKE '%-output-tokens'
AND line_item_usage_type NOT LIKE '%-cache-read-%'
AND line_item_usage_type NOT LIKE '%-cache-write-%'
THEN line_item_unblended_cost ELSE 0 END) AS other_cost
FROM cur_database.bedrock_costs
WHERE year = '2026'
AND month = '06'
AND line_item_product_code = 'AmazonBedrock'
GROUP BY 1
ORDER BY total_cost DESC;
12. FinOps Governance Checklist for Fine-Tuned Model Programs
Before Initiating a Fine-Tuning Job
- [ ] Confirm RAG with S3 Vectors has been benchmarked; document why fine-tuning is preferred
- [ ] Estimate training token count:
dataset_rows × avg_tokens_per_row × epoch_count - [ ] Verify break-even is reachable within 6 months based on projected call volume
- [ ] Tag the customization job with
model-version,team,cost-center,experiment-idbefore submission - [ ] Confirm data labeling budget is included in total project cost
During Training
- [ ] Monitor training loss convergence; stop early if loss plateau is reached before planned epochs (saves tokens)
- [ ] For RFT, set a maximum job duration to cap GPU-hour spend
- [ ] Confirm S3 output bucket for model artifacts has lifecycle policy (avoids perpetual storage of intermediate checkpoints)
After Training
- [ ] Run automatic Model Evaluation before any human evaluation to filter out low-quality runs cheaply
- [ ] Create Application Inference Profile with cost allocation tags before first production inference call
- [ ] Set CMI idle timeout if available, or implement application-level heartbeat to minimize unused 5-minute billing windows
- [ ] Delete superseded model versions from Bedrock after confirming S3 export (keep $1.95/month only for versions in active use)
Ongoing
- [ ] Run monthly TCO Athena query (§11.5) to confirm amortized training cost is <20% of total monthly model cost by month 3
- [ ] Review cache token reconciliation (§11.6) quarterly to catch cost undercounting
- [ ] Establish version retention policy: maximum 3 active Bedrock versions per model family
13. Key Numbers Reference Card
| Item | Rate | Notes |
|---|---|---|
| Titan Text Express SFT | $0.008/1K tokens | Most common enterprise SFT target |
| Llama 2 70B SFT | $0.00799/1K tokens | Legacy; CMI + LoRA preferred |
| Cohere Command SFT | $0.004/1K tokens | Good RAG+instruction baseline |
| Nova Micro SFT (effective) | ~$1.25/M tokens | Includes job overhead |
| RFT (gpt-oss-20b, Qwen3 32B) | $80.00/hour | Hourly, not per-token |
| Model storage | $1.95/model/month | Flat fee; version proliferation adds up |
| CMI (us-east-1) | $0.05718/CMU/minute | 5-minute minimum billing window |
| CMI (eu-central-1) | $0.07144/CMU/minute | 25% regional premium |
| Provisioned Throughput (Llama 2 13B, 1-month) | $21.18/hour | Full-month commitment |
| Human model evaluation | $0.21/task | Plus inference cost |
| RAG Knowledge Base floor (S3 Vectors) | ~$70/month | vs $700+ for OpenSearch Serverless |
| Fine-tuned model break-even vs RAG | ~750K calls/month | Assumes 2K token system prompt eliminated |
Sources
- Amazon Bedrock Pricing – AWS
- Understanding your Amazon Bedrock CUR data – AWS Docs
- Application Inference Profiles – AWS Docs
- Customize Amazon Nova models with Amazon Bedrock fine-tuning – AWS Blog
- Create and manage fine-tuning jobs for Amazon Nova models – AWS Docs
- Amazon Bedrock Custom Model Import real-time cost transparency – AWS What’s New
- Amazon Bedrock Custom Model Import generally available – AWS What’s New
- On-demand deployment for custom Amazon Nova models – AWS What’s New
- Amazon Bedrock Pricing – Cloud Burn analysis
- AWS Bedrock Pricing Optimization Guide – Finout
- AWS Bedrock Pricing – nOps
- LiteLLM Spend Tracking – Statsig
- AWS Data Exports granular operation visibility for Bedrock – AWS What’s New
- Production LLM Fine-Tuning with LoRA & QLoRA on AWS – Mactores