{"id":3810,"library":"spandrel","title":"Spandrel: PyTorch Model Architecture Support","description":"Spandrel is a Python library that provides support for loading and running pre-trained PyTorch models, particularly those used in AI Super-Resolution, restoration, and inpainting. It automatically detects the model architecture and hyperparameters from various model file types, including `.pth`, `.pt`, `.ckpt`, and `.safetensors`. The current version is 0.4.2, and it follows an active release cadence with updates often accompanied by the `spandrel_extra_arches` package for models with restrictive licenses.","status":"active","version":"0.4.2","language":"en","source_language":"en","source_url":"https://github.com/chaiNNer-org/spandrel","tags":["pytorch","model-loading","super-resolution","ai-restoration","deep-learning"],"install":[{"cmd":"pip install spandrel","lang":"bash","label":"Install stable version"},{"cmd":"pip install spandrel spandrel_extra_arches","lang":"bash","label":"Install with extra architectures (non-commercial/private use)"}],"dependencies":[{"reason":"Core dependency for PyTorch models.","package":"torch","optional":false},{"reason":"Provides support for additional model architectures with restrictive licenses (e.g., non-commercial). Not installed by default with `spandrel`.","package":"spandrel_extra_arches","optional":true}],"imports":[{"note":"Internal modules like `__helpers` are not part of the public API and should not be imported directly.","wrong":"from spandrel.__helpers import ModelLoader","symbol":"ModelLoader","correct":"from spandrel import ModelLoader"}],"quickstart":{"code":"import os\nimport torch\nfrom spandrel import ModelLoader\n\n# This is a placeholder for a real .pth model file.\n# In a real scenario, you would have a path to a pre-trained PyTorch model.\n# For demonstration, we'll simulate loading a non-existent file.\n# Replace 'path/to/your/model.pth' with an actual model file path.\n# A common practice is to download models from official repositories.\nmodel_path = os.environ.get('SPANDREL_MODEL_PATH', 'path/to/your/model.pth')\n\n# Ensure the directory for the dummy model exists if needed for testing\n# For a real quickstart, the model_path would point to an existing file.\nif not os.path.exists(model_path):\n    print(f\"[NOTE]: Model file not found at '{model_path}'. This example requires a valid .pth model file.\\n\")\n    print(\"You can download a sample model, e.g., from a Super-Resolution project, and update 'model_path'.\")\n    # Simulate a dummy model for demonstration purposes if no file exists\n    # This part would typically not be in a quickstart as it expects a real file.\n    # For the purpose of making this runnable *without* an actual file,\n    # we'll create a minimal placeholder for the ModelLoader.load_from_file call to fail gracefully.\n    try:\n        # Attempt to load, expecting failure without a real file\n        model = ModelLoader.load_from_file(model_path)\n        # If it miraculously works (e.g., user provided a path to a dummy file),\n        # then proceed to describe interaction.\n        print(f\"Successfully loaded model: {model.name}\")\n        # ModelDescriptor objects (like ImageModelDescriptor) are wrappers around the actual PyTorch model.\n        # They provide a unified interface.\n        # The actual forward pass depends on the model type.\n        # For an ImageModelDescriptor, input is typically a torch.Tensor (batch, channels, height, width).\n        # dummy_input = torch.randn(1, 3, 256, 256) # Example input for an image model\n        # output = model(dummy_input)\n        # print(f\"Model output shape: {output.shape}\")\n    except FileNotFoundError:\n        print(\"Failed to load model as expected, because the file does not exist.\")\n        print(\"Please provide a real .pth model path for a functional example.\")\n    except Exception as e:\n        print(f\"An error occurred during model loading: {e}\")\nelse:\n    try:\n        model = ModelLoader.load_from_file(model_path)\n        print(f\"Successfully loaded model: {model.name} (architecture: {model.architecture.name})\")\n        # Example of accessing metadata\n        if hasattr(model, 'scale'):\n            print(f\"Model scale: {model.scale}x\")\n        if hasattr(model, 'upscale_latent'): # Specific to certain architectures\n            print(f\"Upscale latent: {model.upscale_latent}\")\n\n        # Note: ImageModelDescriptor will NOT convert an image to a tensor.\n        # You need to provide a pre-processed tensor.\n        # For demonstration, we'll create a dummy input tensor if the model expects one.\n        if 'Image' in str(type(model)) or 'Upscaler' in str(type(model)):\n            # Assuming a common image input format: NCHW (batch, channels, height, width)\n            dummy_input = torch.randn(1, 3, 128, 128) # Example: batch size 1, 3 channels, 128x128 image\n            print(f\"Attempting forward pass with dummy input shape: {dummy_input.shape}\")\n            try:\n                output = model(dummy_input)\n                print(f\"Model forward pass successful. Output shape: {output.shape}\")\n            except Exception as e:\n                print(f\"Error during model forward pass with dummy input: {e}\")\n                print(\"The actual input shape and type depend on the specific model architecture.\")\n        else:\n            print(\"Model type not recognized for dummy image input. Skipping forward pass.\")\n\n    except Exception as e:\n        print(f\"Error loading or interacting with model from '{model_path}': {e}\")","lang":"python","description":"This quickstart demonstrates how to load a pre-trained PyTorch model using `ModelLoader.load_from_file`. The `ModelLoader` automatically detects the architecture and provides a unified `ModelDescriptor` object. The example includes a placeholder for a model path and demonstrates how to interact with the loaded model, including accessing metadata and attempting a forward pass with a dummy tensor input. Users should replace the placeholder path with a real `.pth` model file."},"warnings":[{"fix":"Ensure all `.pth` model files originate from reputable and verified sources. Exercise caution with untrusted `.pth` files.","message":"Loading `.pth` files using Python's `pickle` module, which `spandrel` utilizes, poses a security risk due to its vulnerability to arbitrary code execution. `spandrel` attempts to mitigate this by only deserializing certain data types, but it does not fully eliminate the risk. Only load `.pth` files from trusted sources.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Install `spandrel_extra_arches` if you need support for models with restrictive licenses and review the licenses of individual architectures within that package for compliance with your project's use case.","message":"The `spandrel` package contains architectures with permissive licenses (MIT, Apache 2.0, public domain). For architectures with more restrictive licenses (e.g., non-commercial), you need to install `spandrel_extra_arches`. Be aware of the licensing implications of `spandrel_extra_arches` for commercial or closed-source projects.","severity":"gotcha","affected_versions":"All versions"},{"fix":"When defining or calling architecture `load` methods, ensure all arguments are passed as keyword arguments (e.g., `model_loader.load(state_dict=state_dict, key='value')` instead of `model_loader.load(state_dict, 'value')`).","message":"Starting from v0.4.0, all architectures in `spandrel` (and `spandrel_extra_arches`) require keyword arguments for their `load` methods. This change improves clarity and prevents errors when calling architecture-specific loading functions.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Manually convert your image data (e.g., using libraries like Pillow and torchvision.transforms) into a `torch.Tensor` matching the expected input format (e.g., `(batch_size, channels, height, width)` and `torch.float32`) before calling the loaded model.","message":"The `ModelDescriptor` and its variants (e.g., `ImageModelDescriptor`) provided by `spandrel` do not perform image-to-tensor conversion. You must pre-process your image data into a `torch.Tensor` with the correct shape and data type before passing it to the model for inference.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}