Skip to content

Cannot correctly parse some import paths when using config file for LightningCLI #534

@zengchang233

Description

@zengchang233

🐛 Bug report

I would like to use CLI with config.yaml file to manage my project. But I found some classes in TorchAudio cannot be correctly parsed. The error involves importing a window function from Pytorch. For example, if the class doesn't have a window function as the argument explicitly like MFCC or LFCC, it can be parsed and imported successfully. Otherwise, it fails in parsing the class or just identifies the import path as a string (like MelSpectrogram).

To reproduce

from lightning.pytorch.cli import LightningCLI

cli = LightningCLI(run=True, save_config_kwargs={"overwrite": True})
model:
  class_path: models.AudioSystem
  init_args:
    model:
      class_path: models.AudioModel
      init_args:
        feat_dim: 80 # n_feat
        trunc_len: 750
        num_classes: 1000
    feature_extractor:
      class_path: torchaudio.transforms.MelSpectrogram
      init_args:
        sample_rate: 16000
        n_mels: 80
        n_fft: 512
        win_length: 512
        hop_length: 160
        window_fn: torch.hann_window # It is a default argument. Whether configuring it explicitly or not, the error occurred.
    delta_order: 2

Expected behavior

The MelSpectrogram class should be correctly imported and instantiated. But I got some errors as

# Configure the window function explicitly
ValueError: Only possible to serialize an importable object, given <built-in method hann_window of type object at 0x7feed842f840>: module 'torch' has no attribute '_VariableFunctionsClass'

# Don't configure the window function in config file, using the default argument.
Traceback (most recent call last):
  File "/workspace/zengchang/work/antispoofing/train.py", line 128, in <module>
    main()
  File "/workspace/zengchang/work/antispoofing/train.py", line 125, in main
    cli_main()
  File "/workspace/zengchang/work/antispoofing/train.py", line 68, in cli_main
    cli = CustomCLI(
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/lightning/pytorch/cli.py", line 385, in __init__
    self.instantiate_classes()
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/lightning/pytorch/cli.py", line 535, in instantiate_classes
    self.config_init = self.parser.instantiate_classes(self.config)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_deprecated.py", line 141, in patched_instantiate_classes
    cfg = self._unpatched_instantiate_classes(cfg, **kwargs)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_core.py", line 1196, in instantiate_classes
    cfg[subcommand] = subparser.instantiate_classes(cfg[subcommand], instantiate_groups=instantiate_groups)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_deprecated.py", line 141, in patched_instantiate_classes
    cfg = self._unpatched_instantiate_classes(cfg, **kwargs)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_core.py", line 1187, in instantiate_classes
    parent[key] = component.instantiate_classes(value)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 565, in instantiate_classes
    value[num] = adapt_typehints(
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 952, in adapt_typehints
    val = adapt_class_type(val, serialize, instantiate_classes, sub_add_kwargs, prev_val=prev_val)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 1173, in adapt_class_type
    init_args = parser.instantiate_classes(init_args)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_deprecated.py", line 141, in patched_instantiate_classes
    cfg = self._unpatched_instantiate_classes(cfg, **kwargs)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_core.py", line 1187, in instantiate_classes
    parent[key] = component.instantiate_classes(value)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 565, in instantiate_classes
    value[num] = adapt_typehints(
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 952, in adapt_typehints
    val = adapt_class_type(val, serialize, instantiate_classes, sub_add_kwargs, prev_val=prev_val)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_typehints.py", line 1187, in adapt_class_type
    return instantiator_fn(val_class, **{**init_args, **dict_kwargs})
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/jsonargparse/_common.py", line 148, in default_class_instantiator
    return class_type(*args, **kwargs)
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/torchaudio/transforms/_transforms.py", line 593, in __init__
    self.spectrogram = Spectrogram(
  File "/opt/conda/envs/asvspoof5/lib/python3.10/site-packages/torchaudio/transforms/_transforms.py", line 85, in __init__
    window = window_fn(self.win_length) if wkwargs is None else window_fn(self.win_length, **wkwargs)
TypeError: 'str' object is not callable

I have traced the error for using default argument. I found the window_fn is a string torch._VariableFunctionsClass.hann_window. It seems the import path is treated as a string. But even though this path is imported, it will raise an error since the window function should be imported as from torch import hann_window or import torch.hann_window, rather than import torch._VariableFunctionsClass.hann_window.

Environment

  • jsonargparse version: 4.28
  • Python version: 3.10
  • How jsonargparse was installed: pip install "jsonargparse[all]"
  • OS: Ubuntu18.04

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions