{"record":{"id":"f030259f0adb38ad","repo":"FoundationAgents/MetaGPT","slug":"sum-of-exponential-weights-is-0-cannot-normalize","errorCode":null,"errorMessage":"Sum of exponential weights is 0, cannot normalize.","messagePattern":"Sum of exponential weights is 0, cannot normalize\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"metagpt/ext/aflow/scripts/optimizer_utils/data_utils.py","lineNumber":79,"sourceCode":"\n        return sorted_items[selected_index]\n\n    def _compute_probabilities(self, scores, alpha=0.2, lambda_=0.3):\n        scores = np.array(scores, dtype=np.float64)\n        n = len(scores)\n\n        if n == 0:\n            raise ValueError(\"Score list is empty.\")\n\n        uniform_prob = np.full(n, 1.0 / n, dtype=np.float64)\n\n        max_score = np.max(scores)\n        shifted_scores = scores - max_score\n        exp_weights = np.exp(alpha * shifted_scores)\n\n        sum_exp_weights = np.sum(exp_weights)\n        if sum_exp_weights == 0:\n            raise ValueError(\"Sum of exponential weights is 0, cannot normalize.\")\n\n        score_prob = exp_weights / sum_exp_weights\n\n        mixed_prob = lambda_ * uniform_prob + (1 - lambda_) * score_prob\n\n        total_prob = np.sum(mixed_prob)\n        if not np.isclose(total_prob, 1.0):\n            mixed_prob = mixed_prob / total_prob\n\n        return mixed_prob\n\n    def load_log(self, cur_round, path=None, mode: str = \"Graph\"):\n        if mode == \"Graph\":\n            log_dir = os.path.join(self.root_path, \"workflows\", f\"round_{cur_round}\", \"log.json\")\n        else:\n            log_dir = path\n\n        # 检查文件是否存在","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/ext/aflow/scripts/optimizer_utils/data_utils.py#L61-L97","documentation":"Raised by _compute_probabilities when the sum of exponential weights equals exactly 0 after computing exp_weights = exp(alpha * (scores - max(scores))). Mathematically the maximum shifted score is 0 so exp(0)=1 and the sum is at least 1; this branch can only fire with non-finite scores (NaN or +/-inf), e.g. max being inf driving every exp to 0, or NaN propagating through np.sum.","triggerScenarios":"Passing scores containing np.inf (max=inf => shifted=-inf => exp=0 for every element) or NaN round scores, e.g. a round whose validation score was recorded as inf/NaN.","commonSituations":"A scored round stored inf (e.g. 1/0 metric) or NaN (failed evaluation serialized as NaN) in the experience data; upstream parsing writing NaN for missing scores.","solutions":["Inspect the experience/score files for inf or NaN entries and fix the failed round's score or remove that round","Sanitize scores before calling: scores = [s for s in scores if np.isfinite(s)]","Fix the evaluation step that produced a non-finite score so future rounds store finite values"],"exampleFix":"scores = [s for s in scores if np.isfinite(s)]\nprobs = du._compute_probabilities(scores)","handlingStrategy":"validation","validationCode":"import numpy as np\nscores = [s for s in scores if np.isfinite(s)]\nassert scores, \"no finite scores left\"","typeGuard":"def all_finite(scores) -> bool:\n    import numpy as np\n    return bool(np.all(np.isfinite(np.asarray(scores, dtype=np.float64))))","tryCatchPattern":null,"preventionTips":["Never store inf/NaN as round scores in experience files","Sanitize scores with np.isfinite before softmax-style computations"],"tags":["aflow","numeric","nan","softmax"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}