hankcs/HanLP · error · RuntimeError

Call fit or load before evaluate.

Error message

Call fit or load before evaluate.

What it means

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.

Source

Thrown at hanlp/common/torch_component.py:459

        """
        raise NotImplementedError

    def evaluate(self, tst_data, save_dir=None, logger: logging.Logger = None, batch_size=None, output=False, **kwargs):
        """Evaluate test set.

        Args:
            tst_data: Test set, which is usually a file path.
            save_dir: The directory to save evaluation scores or predictions.
            logger: Logger for reporting progress.
            batch_size: Batch size for test dataloader.
            output: Whether to save outputs into some file.
            **kwargs: Not used.

        Returns:
            (metric, outputs) where outputs are the return values of ``evaluate_dataloader``.
        """
        if not self.model:
            raise RuntimeError('Call fit or load before evaluate.')
        if isinstance(tst_data, str):
            tst_data = get_resource(tst_data)
            filename = os.path.basename(tst_data)
        else:
            filename = None
        if output is True:
            output = self.generate_prediction_filename(tst_data if isinstance(tst_data, str) else 'test.txt', save_dir)
        if logger is None:
            _logger_name = basename_no_ext(filename) if filename else None
            logger = self.build_logger(_logger_name, save_dir)
        if not batch_size:
            batch_size = self.config.get('batch_size', 32)
        data = self.build_dataloader(**merge_dict(self.config, data=tst_data, batch_size=batch_size, shuffle=False,
                                                  device=self.devices[0], logger=logger, overwrite=True))
        dataset = data
        while dataset and hasattr(dataset, 'dataset'):
            dataset = dataset.dataset
        num_samples = len(dataset) if dataset else None

View on GitHub (pinned to ddb1299bdd)

Solutions

  1. Move training to a real task component and supply the embedding via its config
  2. Load pretrained vectors directly if you only need embeddings
  3. Subclass and implement the loop yourself for custom training
Defensive patterns

Strategy: type-guard

Validate before calling

if type(model).execute_training_loop is Word2VecEmbedding.execute_training_loop:
    raise TypeError('cannot train this embedding')

Type guard

def is_trainable(m): return 'execute_training_loop' in m.__class__.__dict__

Try / catch

try:
    model.execute_training_loop(...)
except NotImplementedError as e:
    raise RuntimeError(f'{type(model).__name__} cannot be trained') from e

Prevention

When it happens

Trigger: Calling fit() (which internally invokes execute_training_loop) on a Word2VecEmbedding, or calling execute_training_loop directly.

Common situations: 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.

Related errors


AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27). Data as JSON: /api/errors/992306d2950d9b4d. Report an issue: GitHub.