Repository: ggml-org/llama.cpp
Pull request: lookup, lookahead: fix crash when n_ctx not specified

## Summary

Fixes a crash in `llama-lookup` and `llama-lookahead` when run without explicit `-c` flag:

```
GGML_ASSERT(batch.seq_id[batch.n_tokens] && "llama_batch size exceeded")
```

## Root Cause

Both examples use `params.n_ctx` directly for batch initialization:

```cpp
// lookup.cpp:109
llama_batch batch_tgt = llama_batch_init(params.n_ctx, 0, 1);

// lookahead.cpp:118
llama_batch batch = llama_batch_init(params.n_ctx, 0, W + G + 1);
```

Since #16653 changed the default `n_ctx` to 0 (for GPU auto-fitting), `params.n_ctx` remains 0 even after the context is properly initialized. This creates a zero-sized batch that crashes on the first `common_batch_add()`.

## Bug History

This bug was **dormant for 2+ years**:

| Date | PR | Default n_ctx | Effect |
|------|-----|---------------|--------|
| Nov 2023 | #4207 | 512 | lookahead.cpp created - **works** |
| Dec 2023 | #4484 | 512 | lookup.cpp created - **works** |
| Nov 2024 | #10136 | 4096 | Default increased - **works** |
| **Dec 2025** | **#16653** | **0** | Auto-fitting enabled - **CRASHES** |

The pattern was always incorrect, but only triggered when `n_ctx` default became 0.

## Fix

Use `llama_n_ctx(ctx)` to get the actual runtime context size:

```cpp
// Before
llama_batch batch_tgt = llama_batch_init(params.n_ctx, 0, 1);

// After
llama_batch batch_tgt = llama_batch_init(llama_n_ctx(ctx), 0, 1);
```

This matches:
- The pattern already used in `lookup.cpp:72` for `max_context_size`
- The pattern used in `speculative.cpp` and `speculative-simple.cpp`

## Testing

```bash
# Before fix (crashes):
llama-lookup -m model.gguf -f prompt.txt --draft 4 -n 50
# GGML_ASSERT(batch.seq_id[batch.n_tokens] && "llama_batch size exceeded")

# After fix (works):
llama-lookup -m model.gguf -f prompt.txt --draft 4 -n 50
# n_accept = 1, accept = 12.500%
```

## Note

`llama-lookahead` has a separate pre-existing issue with sequence initialization (`n_seq_max=1` when it needs `W+G+1`) that is unrelated to this batch size fix.

Changed files:
filename: examples/lookahead/lookahead.cpp
patch: @@ -50,6 +50,12 @@ int main(int argc, char ** argv) {
     const int N = 5;  // n-gram size
     const int G = 15; // max verification n-grams
 
+    // lookahead requires W + G + 1 sequences for parallel Jacobi decoding
+    params.n_parallel = W + G + 1;
+
+    // unified KV cache is required for coupled sequences in batch splitting
+    params.kv_unified = true;
+
     // init llama.cpp
     llama_backend_init();
     llama_numa_init(params.numa);
@@ -115,7 +121,7 @@ int main(int argc, char ** argv) {
     // seq_id == 0           : the current input token
     // seq_id [1, W]         : tokens from the past N - 1 Jacobi iterations
     // seq_id [W + 1, W + G] : verification n-grams
-    llama_batch batch = llama_batch_init(params.n_ctx, 0, W + G + 1);
+    llama_batch batch = llama_batch_init(llama_n_ctx(ctx), 0, W + G + 1);
 
     // target model sampling context
     struct common_sampler * smpl = common_sampler_init(model, params.sampling);

filename: examples/lookup/lookup.cpp
patch: @@ -106,7 +106,7 @@ int main(int argc, char ** argv){
 
     std::vector<llama_token> draft;
 
-    llama_batch batch_tgt = llama_batch_init(params.n_ctx, 0, 1);
+    llama_batch batch_tgt = llama_batch_init(llama_n_ctx(ctx), 0, 1);
 
     const auto t_dec_start = ggml_time_us();