huggingface/transformers · critical · ValueError
No positive solution (root = {})
Error message
No positive solution (root = {}) What it means
Raised by PagedAttentionCache._solve_quadratic when the quadratic has real roots but the largest one is negative: even the best solution is a negative token count. The memory budget cannot fit any positive batch — constant costs (model/activation baseline or the fixed KV blocks) already exceed available_memory.
Source
Thrown at src/transformers/generation/continuous_batching/cache.py:750
memory_footprint = self.compute_memory_footprint(max_batch_tokens, num_blocks)
if memory_footprint > self.available_memory:
raise MemoryError(
f"Memory footprint {memory_footprint} is more than available memory {self.available_memory}"
)
if max_batch_tokens <= 0 or num_blocks <= 0:
raise ValueError(f"Invalid values: max_batch_tokens = {max_batch_tokens}, num_blocks = {num_blocks}")
return max_batch_tokens, num_blocks
def _solve_quadratic(self, a: float, b: float, c: float) -> int:
"""Largest positive root of a·x² + b·x + c = 0. Falls back to linear when a == 0. Rounded down."""
if a == 0:
return int(-c / b)
discriminant = b**2 - 4 * a * c
if discriminant < 0:
raise ValueError(f"No real solution (discriminant = {discriminant})")
root = (-b + sqrt(discriminant)) / (2 * a)
if root < 0:
raise ValueError(f"No positive solution (root = {root})")
return int(floor(root))
# Formatting is disabled because of comment indentation, which improves readability.
# fmt: off
def _equation_coefficients(self, peak_deltas: tuple[int, ...]) -> tuple[int, ...]:
"""Given some deltas corresponding to an activation peak, returns the coefficients for the memory polynomial of
that peak. The memory polynomial is described in that class docstring."""
delta_m, delta_n, delta_mm, delta_mn = peak_deltas
i = torch.int32.itemsize # size of int32 in bytes, used for index, input_ids, ...
a = self.activation_dtype.itemsize # for now, the cache and the activation have the same dtype
c = self.cache_dtype.itemsize
k = self.io_multiplier # 1 sync, 2 async (IO tensors only)
# -- N terms: cost per cache page --------------------------------------------------
coeff_n = (
delta_n # activation peak: N-proportional part
+ 2 * self.group_size * self.page_size * c # kv_cache: 2 * group_size * [N, page_size] * cache_dtypeView on GitHub (pinned to a597f97485)
Solutions
- Free device memory before manager creation (del tensors, torch.cuda.empty_cache())
- Lower num_blocks or max_batch_tokens explicit settings
- Shrink memory per block: smaller cache dtype, smaller block_size, fewer KV heads (GQA model)
- Verify the cache sees the right device and dtype (model.dtype / cache_dtype)
Example fix
# before manager = model.continuous_batching(config_with_huge_num_blocks) # after torch.cuda.empty_cache() manager = model.continuous_batching(config_with_reduced_num_blocks)
Defensive patterns
Strategy: validation
Validate before calling
free_b, _ = torch.cuda.mem_get_info()
if free_b <= 0:
raise RuntimeError('No free device memory for the paged cache') Try / catch
try:
manager = model.continuous_batching(config=cfg)
except ValueError as e:
if 'No positive solution' in str(e):
torch.cuda.empty_cache()
manager = model.continuous_batching(config=cfg)
else:
raise Prevention
- Free memory before sizing
- Verify model.dtype and cache device are what you expect
- Halve explicit num_blocks on memory errors
When it happens
Trigger: Same solve paths as the discriminant error: N-given branch (num_blocks explicit) or M=m·N substitution during auto-sizing, when -b/(2a)-shifted roots are both negative because c>0 and b>0 (positive constant cost against the budget).
Common situations: available_memory effectively exhausted by prior allocations; num_blocks too large relative to memory; wrong device or dtype reported to the cache so the budget is computed against the wrong pool.
Related errors
- No real solution (discriminant = {})
- Invalid values: max_batch_tokens = {}, num_blocks = {}
- Failed to allocate {} blocks for request {}
- Memory footprint {} is more than available memory {}
- No requests can be scheduled and no requests can be offloade
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/2422af62616881a3.
Report an issue: GitHub.