{"record":{"id":"992306d2950d9b4d","repo":"hankcs/HanLP","slug":"call-fit-or-load-before-evaluate","errorCode":null,"errorMessage":"Call fit or load before evaluate.","messagePattern":"Call fit or load before evaluate\\.","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"hanlp/common/torch_component.py","lineNumber":459,"sourceCode":"        \"\"\"\n        raise NotImplementedError\n\n    def evaluate(self, tst_data, save_dir=None, logger: logging.Logger = None, batch_size=None, output=False, **kwargs):\n        \"\"\"Evaluate test set.\n\n        Args:\n            tst_data: Test set, which is usually a file path.\n            save_dir: The directory to save evaluation scores or predictions.\n            logger: Logger for reporting progress.\n            batch_size: Batch size for test dataloader.\n            output: Whether to save outputs into some file.\n            **kwargs: Not used.\n\n        Returns:\n            (metric, outputs) where outputs are the return values of ``evaluate_dataloader``.\n        \"\"\"\n        if not self.model:\n            raise RuntimeError('Call fit or load before evaluate.')\n        if isinstance(tst_data, str):\n            tst_data = get_resource(tst_data)\n            filename = os.path.basename(tst_data)\n        else:\n            filename = None\n        if output is True:\n            output = self.generate_prediction_filename(tst_data if isinstance(tst_data, str) else 'test.txt', save_dir)\n        if logger is None:\n            _logger_name = basename_no_ext(filename) if filename else None\n            logger = self.build_logger(_logger_name, save_dir)\n        if not batch_size:\n            batch_size = self.config.get('batch_size', 32)\n        data = self.build_dataloader(**merge_dict(self.config, data=tst_data, batch_size=batch_size, shuffle=False,\n                                                  device=self.devices[0], logger=logger, overwrite=True))\n        dataset = data\n        while dataset and hasattr(dataset, 'dataset'):\n            dataset = dataset.dataset\n        num_samples = len(dataset) if dataset else None","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/hankcs/HanLP/blob/ddb1299bddff079e447af52ec12549c50636bfa8/hanlp/common/torch_component.py#L441-L477","documentation":"execute_training_loop on Word2VecEmbedding always raises NotImplementedError since pretrained embeddings are inference-only and cannot run an epoch loop. HanLP reserves the method signature for interface compatibility with trainable components but blocks it here.","triggerScenarios":"Calling fit() (which internally invokes execute_training_loop) on a Word2VecEmbedding, or calling execute_training_loop directly.","commonSituations":"Attempting to fine-tune word vectors via the standard HanLP training API; reusing a training script with a non-trainable embedding as the top-level model.","solutions":["Move training to a real task component and supply the embedding via its config","Load pretrained vectors directly if you only need embeddings","Subclass and implement the loop yourself for custom training"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if type(model).execute_training_loop is Word2VecEmbedding.execute_training_loop:\n    raise TypeError('cannot train this embedding')","typeGuard":"def is_trainable(m): return 'execute_training_loop' in m.__class__.__dict__","tryCatchPattern":"try:\n    model.execute_training_loop(...)\nexcept NotImplementedError as e:\n    raise RuntimeError(f'{type(model).__name__} cannot be trained') from e","preventionTips":["Route training through task components","Validate config's model type before launching training"],"tags":["hanlp","training-loop","embedding","not-implemented"],"backgroundTag":"not-implemented-error","analyzedSha":"ddb1299bddff079e447af52ec12549c50636bfa8","analyzedAt":"2026-08-27T03:36:54.287Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}