{"record":{"id":"2422af62616881a3","repo":"huggingface/transformers","slug":"no-positive-solution-root","errorCode":null,"errorMessage":"No positive solution (root = {})","messagePattern":"No positive solution \\(root = (.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"src/transformers/generation/continuous_batching/cache.py","lineNumber":750,"sourceCode":"        memory_footprint = self.compute_memory_footprint(max_batch_tokens, num_blocks)\n        if memory_footprint > self.available_memory:\n            raise MemoryError(\n                f\"Memory footprint {memory_footprint} is more than available memory {self.available_memory}\"\n            )\n        if max_batch_tokens <= 0 or num_blocks <= 0:\n            raise ValueError(f\"Invalid values: max_batch_tokens = {max_batch_tokens}, num_blocks = {num_blocks}\")\n        return max_batch_tokens, num_blocks\n\n    def _solve_quadratic(self, a: float, b: float, c: float) -> int:\n        \"\"\"Largest positive root of a·x² + b·x + c = 0. Falls back to linear when a == 0. Rounded down.\"\"\"\n        if a == 0:\n            return int(-c / b)\n        discriminant = b**2 - 4 * a * c\n        if discriminant < 0:\n            raise ValueError(f\"No real solution (discriminant = {discriminant})\")\n        root = (-b + sqrt(discriminant)) / (2 * a)\n        if root < 0:\n            raise ValueError(f\"No positive solution (root = {root})\")\n        return int(floor(root))\n\n    # Formatting is disabled because of comment indentation, which improves readability.\n    # fmt: off\n    def _equation_coefficients(self, peak_deltas: tuple[int, ...]) -> tuple[int, ...]:\n        \"\"\"Given some deltas corresponding to an activation peak, returns the coefficients for the memory polynomial of\n        that peak. The memory polynomial is described in that class docstring.\"\"\"\n        delta_m, delta_n, delta_mm, delta_mn = peak_deltas\n\n        i = torch.int32.itemsize             # size of int32 in bytes, used for index, input_ids, ...\n        a = self.activation_dtype.itemsize             # for now, the cache and the activation have the same dtype\n        c = self.cache_dtype.itemsize\n        k = self.io_multiplier               # 1 sync, 2 async (IO tensors only)\n\n        # -- N terms: cost per cache page --------------------------------------------------\n        coeff_n = (\n            delta_n                                      # activation peak: N-proportional part\n            + 2 * self.group_size * self.page_size * c   # kv_cache: 2 * group_size * [N, page_size] * cache_dtype","sourceCodeStart":732,"sourceCodeEnd":768,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/generation/continuous_batching/cache.py#L732-L768","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)"],"exampleFix":"# before\nmanager = model.continuous_batching(config_with_huge_num_blocks)\n\n# after\ntorch.cuda.empty_cache()\nmanager = model.continuous_batching(config_with_reduced_num_blocks)","handlingStrategy":"validation","validationCode":"free_b, _ = torch.cuda.mem_get_info()\nif free_b <= 0:\n    raise RuntimeError('No free device memory for the paged cache')","typeGuard":null,"tryCatchPattern":"try:\n    manager = model.continuous_batching(config=cfg)\nexcept ValueError as e:\n    if 'No positive solution' in str(e):\n        torch.cuda.empty_cache()\n        manager = model.continuous_batching(config=cfg)\n    else:\n        raise","preventionTips":["Free memory before sizing","Verify model.dtype and cache device are what you expect","Halve explicit num_blocks on memory errors"],"tags":["memory","solver","continuous-batching","math"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}