{"record":{"id":"97b8689d0b89d295","repo":"PaddlePaddle/PaddleOCR","slug":"is-not-supported-in-multiloss-yet","errorCode":null,"errorMessage":"{} is not supported in MultiLoss yet","messagePattern":"(.+?) is not supported in MultiLoss yet","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"ppocr/losses/rec_multi_loss.py","lineNumber":62,"sourceCode":"        # batch [image, label_ctc, label_sar, length, valid_ratio]\n        for name, loss_func in self.loss_funcs.items():\n            if name == \"CTCLoss\":\n                loss = (\n                    loss_func(predicts[\"ctc\"], batch[:2] + batch[3:])[\"loss\"]\n                    * self.weight_1\n                )\n            elif name == \"SARLoss\":\n                loss = (\n                    loss_func(predicts[\"sar\"], batch[:1] + batch[2:])[\"loss\"]\n                    * self.weight_2\n                )\n            elif name == \"NRTRLoss\":\n                loss = (\n                    loss_func(predicts[\"gtc\"], batch[:1] + batch[2:])[\"loss\"]\n                    * self.weight_2\n                )\n            else:\n                raise NotImplementedError(\n                    \"{} is not supported in MultiLoss yet\".format(name)\n                )\n            self.total_loss[name] = loss\n            total_loss += loss\n        self.total_loss[\"loss\"] = total_loss\n        return self.total_loss\n","sourceCodeStart":44,"sourceCodeEnd":69,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/losses/rec_multi_loss.py#L44-L69","documentation":"MultiLoss (used by GTC-style recognition heads) iterates over configured loss names and only knows 'CTCLoss', 'SARLoss' and 'NRTRLoss'. Each branch pulls the matching prediction tensor from predicts['ctc']/'sar'/'gtc'; any other name raises NotImplementedError with the offending name.","triggerScenarios":"Configuring MultiLoss with an unsupported name, e.g. MultiLoss(['CTCLoss','RCLoss']) or a typo like 'NRTRLoss' (case matters: the branch checks exact 'NRTRLoss'); also enabling SAR/NRTR loss without a head that outputs the corresponding key.","commonSituations":"Customizing a rec model with GTC loss and adding a loss the multi-loss wrapper doesn't dispatch on; case mismatch when porting config snippets between models.","solutions":["Restrict names to exactly 'CTCLoss', 'SARLoss', 'NRTRLoss' in the MultiLoss config","Ensure the paired head actually outputs the keys the branch reads: predicts['ctc'], predicts['sar'], predicts['gtc']","For a new loss type, extend MultiLoss with an elif branch before the else (it is a small explicit dispatcher, not a registry)"],"exampleFix":"# before\nloss_list = ['CTCLoss', 'NRTRLoss']  # NotImplementedError\n\n# after\nloss_list = ['CTCLoss', 'NRTRLoss']","handlingStrategy":"validation","validationCode":"MULTI_LOSS_NAMES = {'CTCLoss', 'SARLoss', 'NRTRLoss'}\nfor name in loss_list:\n    assert name in MULTI_LOSS_NAMES, f'MultiLoss does not support {name!r}; use {sorted(MULTI_LOSS_NAMES)}'","typeGuard":"def is_multi_loss_name(n: str) -> bool:\n    return n in {'CTCLoss', 'SARLoss', 'NRTRLoss'}","tryCatchPattern":null,"preventionTips":["Names are case-sensitive exact matches ('NRTRLoss', not 'NRTRLoss')","Ensure the head provides predicts['ctc']/['sar']/['gtc'] for each enabled loss","Schema-check GTC loss lists in config validation before training"],"tags":["config","loss","recognition","enum-value"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}