How the FaceSwap Plugin System Works for Models, Trainers, and Converters
FaceSwap uses a convention-based PluginLoader class in plugins/plugin_loader.py to dynamically import model, trainer, and converter classes from the plugins/ directory at runtime, mapping hyphenated names to title-cased Python classes using standard import machinery.
The FaceSwap plugin system provides a flexible architecture for extending deepfake training and conversion capabilities through three distinct extension points: models, trainers, and converters. By leveraging dynamic module importing and strict naming conventions implemented in plugins/plugin_loader.py, the system allows developers to add new neural network architectures, training loops, and output formats simply by placing correctly named Python files in designated subdirectories of the plugins/ folder.
FaceSwap Plugin Architecture Overview
The FaceSwap plugin system organizes extensions into three categories, each with dedicated directories and abstract base classes that define the contract between the framework and the plugin.
Models (plugins/train/model/): Neural network architectures that define the autoencoder structure. All models inherit from ModelBase defined in plugins/train/model/_base/update.py. Examples include original.py and phaze_a.py.
Trainers (plugins/train/trainer/): Training loop implementations that handle batch processing, loss calculation, and optimization. These inherit from TrainerBase in plugins/train/trainer/_base.py. The default implementation resides in plugins/train/trainer/original.py.
Converters (plugins/convert/<category>/): Post-processing and output modules organized by category (e.g., writer/, mask/). Writers inherit from the Output base class in plugins/convert/writer/_base.py, with concrete implementations like pillow.py providing specific output formats.
How the PluginLoader Dynamically Discovers Extensions
At the heart of the FaceSwap plugin system is the PluginLoader class in plugins/plugin_loader.py. This utility implements a convention-based discovery mechanism that maps string names to Python classes without hardcoded imports.
The loader normalizes plugin names by converting hyphens to underscores (my-model → my_model) to match Python module naming conventions. It then constructs the full module path (e.g., plugins.model.original) and uses import_module from Python's import machinery to load the file dynamically.
Once imported, the loader retrieves the class by applying title-casing to the module name. For example, original.py contains the class Original, and phaze_a.py contains PhazeA. This strict naming convention ensures predictable class resolution.
The PluginLoader also provides discovery methods for listing available plugins. get_available_models() scans plugins/train/model/ for non-private Python files (excluding those starting with underscore), while get_available_convert_plugins(category) performs similar scans for converter categories like writer or mask.
Loading Models, Trainers, and Converters
The FaceSwap plugin system exposes three primary loader methods that scripts use to instantiate the necessary components for training and conversion workflows.
Loading a Training Model
To load a model architecture, call PluginLoader.get_model(name). This returns the class (not an instance) defined in the corresponding module.
from plugins.plugin_loader import PluginLoader
# Load the Original model class
ModelCls = PluginLoader.get_model("original")
# Returns: <class 'plugins.train.model.original.Model'>
# Instantiate with default configuration
model = ModelCls()
# Access the underlying Keras model via model.model
The model instance encapsulates the neural network graph, typically stored in the model attribute as a Keras/TensorFlow model object.
Loading a Trainer
Trainers orchestrate the training loop. Use PluginLoader.get_trainer(name) to retrieve the trainer class, then instantiate it with a model instance and training parameters.
# Load the Original trainer
TrainerCls = PluginLoader.get_trainer("original")
# Returns: <class 'plugins.train.trainer.original.Trainer'>
# Instantiate with model and batch configuration
trainer = TrainerCls(model=model, batch_size=8)
The trainer implements the train_batch method (defined abstractly in TrainerBase) to handle forward passes, loss computation, and backpropagation.
Loading a Converter
Converters handle post-processing and output generation. The loader requires a category (e.g., "writer") and a plugin name.
# Load the Pillow image writer
WriterCls = PluginLoader.get_converter("writer", "pillow")
# Returns: <class 'plugins.convert.writer.pillow.Writer'>
# Instantiate with output directory
writer = WriterCls(output_folder="/tmp/output")
Writer plugins inherit from the Output base class in plugins/convert/writer/_base.py and implement pre_encode, write, and optional close methods.
Plugin Contracts and Base Classes
Each FaceSwap plugin type enforces a contract through abstract base classes located in _base modules. These contracts ensure that the core application can interact with plugins without knowing their specific implementations.
ModelBase in plugins/train/model/_base/update.py
The ModelBase class defines the interface for neural network architectures. Concrete models like Original in plugins/train/model/original.py and PhazeA in plugins/train/model/phaze_a.py inherit from this base. The base class typically specifies methods for building the network graph, saving and loading weights, and configuring input/output shapes.
TrainerBase in plugins/train/trainer/_base.py
TrainerBase establishes the training loop contract. It declares abstract methods such as train_batch that subclasses must implement. The original trainer in plugins/train/trainer/original.py provides a concrete implementation handling TensorFlow/Keras training operations, including gradient computation and optimizer steps.
Output Base Class for Converters
For conversion plugins, the Output base class in plugins/convert/writer/_base.py defines the interface for output generation. Writers such as pillow.py implement pre_encode (frame preparation), write (actual file output), and close (resource cleanup). This structure allows the conversion pipeline to switch between different output formats without modifying the core logic.
Summary
- The FaceSwap plugin system uses a central PluginLoader class in
plugins/plugin_loader.pyto dynamically import model, trainer, and converter classes at runtime. - Plugins reside in specific subdirectories:
plugins/train/model/for architectures,plugins/train/trainer/for training loops, andplugins/convert/<category>/for post-processing. - The loader enforces strict naming conventions: hyphenated names normalize to underscores for modules, and class names must be title-cased versions of the module name (e.g.,
original.pycontains classOriginal). - Each plugin type implements a specific abstract base class—ModelBase, TrainerBase, or Output—ensuring consistent interfaces for the core application.
- Discovery methods like
get_available_models()andget_available_convert_plugins()enable runtime enumeration of available extensions without hardcoding.
Frequently Asked Questions
How does FaceSwap discover new plugins without modifying the core code?
FaceSwap discovers plugins by scanning specific filesystem directories at runtime. The PluginLoader walks the plugins/train/model/, plugins/train/trainer/, and plugins/convert/<category>/ directories, looking for Python files that do not start with an underscore. When a new file following the naming conventions is added to these directories, it becomes immediately available through the loader methods without requiring changes to the central configuration or import statements.
What naming convention must a FaceSwap plugin follow to load correctly?
A FaceSwap plugin must follow a strict naming convention where the module filename uses lowercase with underscores (e.g., my_model.py or phaze_a.py), and the main class inside that file must be the title-cased version of the filename without the extension (e.g., MyModel or PhazeA). Additionally, any hyphens in the requested plugin name are normalized to underscores before import (e.g., requesting "my-model" loads my_model.py).
Can I use a custom trainer with an existing model in FaceSwap?
Yes, the FaceSwap plugin system decouples models from trainers, allowing you to mix and match compatible implementations. You can load an existing model architecture using PluginLoader.get_model("original") and then load a different trainer using PluginLoader.get_trainer("custom"), provided the custom trainer inherits from TrainerBase in plugins/train/trainer/_base.py and implements the required train_batch method with the expected signature for the model's data format.
Where are the base classes defined that FaceSwap plugins must implement?
The base classes that define the plugin contracts are located in _base modules within each plugin category. For models, the base class ModelBase is defined in plugins/train/model/_base/update.py. For trainers, TrainerBase is located in plugins/train/trainer/_base.py. For converter writers and other conversion plugins, the Output base class is found in plugins/convert/writer/_base.py. These abstract base classes specify the methods and properties that concrete plugins must implement to integrate with the FaceSwap pipeline.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →