1. Serving Options: Hosted APIs vs. Self-Hosted Inference
This is Week 18's open-vs-closed decision made operational. A hosted API (calling a provider's endpoint) means no infrastructure to manage, automatic scaling, and per-token pricing — ideal for most projects, especially at low-to-moderate volume. Self-hosting (running an open-weight model, Week 18, on your own or rented GPUs) trades that convenience for control over data residency, no per-token cost ceiling, and the ability to serve a model you fine-tuned yourself (Weeks 19–20) exactly as trained.
# Hosted API tends to win when:
# - Usage volume is low-to-moderate (per-token cost stays manageable)
# - You need the strongest available model with zero ops overhead
# Self-hosting tends to win when:
# - Volume is high and sustained (fixed GPU cost beats per-token cost at scale)
# - Data cannot leave your infrastructure
# - You're serving a custom fine-tuned/LoRA-adapted model (Weeks 19-20) directly
2. Latency, Throughput & Batching
Latency is how long a single request takes; throughput is how many requests a system can serve per unit time. For LLMs specifically, two factors dominate both: the causal generation loop (Week 17) means output tokens are produced one at a time, and attention's quadratic cost (Week 15) means longer inputs slow every step of that generation down.
# Total latency for a request roughly decomposes into:
# - Time to first token (TTFT): processing the full input context before generation starts
# - Time per output token: generation happens one token at a time, sequentially
# - Total latency ~= TTFT + (output_tokens * time_per_token)
# A long RAG context (Week 22) or a long agent history (Week 23) directly increases TTFT,
# while a longer requested response directly increases total generation time
Batching — processing multiple requests' token-generation steps together on the same GPU — is the standard way serving infrastructure improves throughput, at the cost of potentially added latency for any individual request while it waits to be batched with others. This is a direct, practical instance of a batch-size tradeoff you first saw conceptually in Week 12's training loops, now applied to inference instead of training.
3. Cost Modeling for LLM Usage at Scale
Hosted APIs typically price by token, separately for input and output — which means Week 17's context-window budgeting is directly, literally a cost calculation, not just an architectural constraint.
price_per_1k_input = 0.003 # example pricing, illustrative only
price_per_1k_output = 0.015
def estimate_cost(input_tokens, output_tokens, requests_per_day):
daily_input_cost = (input_tokens / 1000) * price_per_1k_input * requests_per_day
daily_output_cost = (output_tokens / 1000) * price_per_1k_output * requests_per_day
return daily_input_cost + daily_output_cost
# A RAG pipeline (Week 22) with a large retrieved context is an INPUT-token-heavy cost;
# a long generated response is an OUTPUT-token-heavy cost -- they're priced differently
Notice output tokens are typically priced higher than input tokens (generation is more computationally expensive per token than processing existing context) — meaning "ask the model to be more concise" is a legitimate, meaningful cost lever, not just a style preference. Multiplying a per-request cost by realistic daily volume, as this snippet does, is what turns "this feature works" into "this feature is affordable" — a distinction many prototypes never actually check before shipping.
4. Caching & Prompt/Response Optimization
Two cheap wins reduce both cost and latency without touching the model at all.
import hashlib
cache = {}
def cached_generate(prompt):
key = hashlib.sha256(prompt.encode()).hexdigest()
if key in cache:
return cache[key] # skip the model call entirely for a repeated prompt
result = call_llm(prompt)
cache[key] = result
return result
Response caching avoids paying for (and waiting on) an identical request twice — valuable for common queries in a support bot or repeated tool descriptions in an agent (Week 23). Many providers also support prompt caching, where a long, unchanged prefix (a system prompt, a large RAG context reused across a conversation) is cached server-side so subsequent requests reprocess only the new part of the input — directly cutting the TTFT cost from Section 2 for exactly the kind of long, mostly-static context Week 22's RAG pipelines produce.
5. Monitoring a Live LLM Application
Once deployed, an LLM application needs the same kind of operational visibility as any production system, plus a few LLM-specific signals: token usage and cost per request (to catch a cost regression early), latency percentiles (not just averages — Week 3's lesson on medians and percentiles applies directly here), and eval-suite scores (Week 24) tracked over time rather than checked only once before launch.
# Version prompts and model choices explicitly, the same way you'd version code
config = {
"version": "v3",
"model": "some-model-v2",
"system_prompt": "...",
"rollback_target": "v2", # what to revert to if v3 regresses
}
# Track Week 24's eval suite score per version -- a prompt or model change
# that regresses the eval score is a signal to roll back, exactly like a
# failed test in ordinary software deployment
Treating prompts and model versions with the same discipline as application code — versioned, tested against a fixed eval suite before rollout, and quick to roll back — is what actually separates a prototype from a production system. It's the same engineering instinct as Week 6's "don't tune against your test set" discipline, applied to production changes instead of a training run.
6. Hands-on Exercise
Deploy an LLM feature behind a simple API and find one real cost optimization
Reuse the Week 22 RAG pipeline or Week 23 agent.
Requirements:
- Wrap your chosen system in a simple API endpoint (a single route using any lightweight framework is enough).
- Log token counts (input and output) and latency for every request.
- Using Section 3's cost model, estimate the daily cost at three different volumes (e.g. 100, 10,000, and 1,000,000 requests/day) and note where the shape of the decision (hosted vs. self-hosting, from Section 1) might change.
- Add response caching (Section 4) for repeated identical requests, and measure the latency/cost improvement on a workload with realistic repetition.
- Identify one concrete change (shorter system prompt, smaller retrieved context, a cheaper model for simple cases) that reduces cost, and measure its actual effect on both cost and your Week 24 eval suite's score — did quality hold up?
Always re-run your Week 24 eval suite after any cost optimization — a change that cuts cost by shrinking context or switching models can just as easily cut quality, and the only way to know is to measure it, not assume it.
7. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
Why does a longer RAG-retrieved context primarily affect time-to-first-token rather than the per-output-token generation speed?
Why does a longer RAG-retrieved context primarily affect time-to-first-token rather than the per-output-token generation speed?
The entire input context must be processed by attention (Week 15) before generation of the first output token can begin, and attention's cost grows with sequence length — a longer input directly increases that upfront processing time (TTFT). Once generation starts, each subsequent output token's cost is comparatively less affected by the original input length.
Q2
Why are output tokens typically priced higher than input tokens by hosted API providers?
Why are output tokens typically priced higher than input tokens by hosted API providers?
Generating tokens happens sequentially, one at a time, via the causal decoding loop, while processing input context (up to the first generated token) can be done more efficiently in parallel across the whole input. This asymmetric computational cost is reflected in pricing, which is also why asking a model to be more concise is a legitimate cost-reduction strategy.
Q3
What's the tradeoff batching introduces between throughput and latency?
What's the tradeoff batching introduces between throughput and latency?
Batching processes multiple requests together, which improves overall throughput (more requests served per unit of GPU time). But an individual request may need to wait for enough other requests to arrive before its batch is processed, which can add latency to that specific request — a throughput/latency tradeoff similar in spirit to the batch-size choices made during training in Week 12.
Q4
Why should a cost-reducing change (like a shorter prompt or cheaper model) always be re-checked against an eval suite before shipping?
Why should a cost-reducing change (like a shorter prompt or cheaper model) always be re-checked against an eval suite before shipping?
Reducing context, switching to a smaller model, or shortening a prompt can just as easily degrade output quality as it reduces cost — the only way to know whether the tradeoff is acceptable is to measure it against the Week 24 eval suite, the same way any model or prompt change should be validated rather than assumed safe.