# DiffEngine's interface is a config file name, and its output directory is written for resuming

> A Python toolbox for training diffusion models on top of diffusers and MMEngine, where a run is started by naming one of the pre-defined configs and everything that run produces lands in a work_dirs directory with checkpoints, logs and a PEFT adapter laid out for inference.

**okotaku/diffengine** — Diffusers training with mmengine

- Repository: https://github.com/okotaku/diffengine
- Stars: 101 · Forks: 10
- Language: Python
- License: Apache-2.0
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/okotaku-diffengine

## A run is started by naming a config, not by passing flags

The interface is a file name. Pre-defined configs live in a configs directory inside the package, and the documented walkthrough picks one to train a DreamBooth model with the Stable Diffusion algorithm, naming the config stable_diffusion_v15_dreambooth_lora_dog and pointing at the file that defines it under configs/stable_diffusion_dreambooth. Training is then a single command:

```bash
pip install git+https://github.com/okotaku/diffengine.git
```

```bash
diffengine train stable_diffusion_v15_dreambooth_lora_dog
```

There is no flag for the learning rate, no flag for the rank and no flag for the batch size in the documented path, because those are settings inside the config file. That is MMEngine's contribution made visible: hyperparameters, loss functions and other settings are customised by editing configuration rather than by assembling a command line, and the trade is that every run has to be committed or copied if you want to keep it.

## The work_dirs tree is laid out for resuming and for inference

Outputs go to a directory named after the config, and its shape is worth reading because it tells you what the tool considers durable. A timestamped subdirectory holds the log file and a vis_data folder containing the log as JSON, a copy of the config used for that experiment, and a vis_image directory of visualisations from each step. Then iter_1000.pth is a checkpoint written each step, and last_checkpoint records the most recent one so a run can be resumed. The piece aimed at inference is a step999 directory containing a unet subdirectory with adapter_config.json and adapter_model.bin, described as the weight for inferencing with diffusers.pipeline. So the same run directory serves three purposes at once, a log for reading, a checkpoint for resuming, and a PEFT adapter for shipping.

## Inference loads a PEFT adapter into a diffusers pipeline

The documented inference path is short and assumes you already know diffusers. You point DiffusionPipeline.from_pretrained at a base model identifier, in the example the Stable Diffusion 1.5 repository, with a torch dtype of float16, move the pipeline to cuda, and then overwrite the pipeline's unet with PeftModel.from_pretrained pointed at the checkpoint's unet directory and an adapter name of default. The same conditional treatment applies to the text encoder: if a text_encoder directory exists inside the checkpoint, it is replaced the same way. That conditional is the detail that matters, because it is what lets a LoRA run that trained only the unet be loaded without the script failing on a missing adapter. The training output and the inference code are designed to meet at that directory.

## The README and the manifest disagree about the PyTorch floor

Installation is a pip install from the git URL, with one prerequisite stated beforehand: PyTorch 2.0 or newer should already be installed, following the official PyTorch guide. The manifest asks for more than that. Its declared dependencies are torch>=2.1.2 and torchvision>=0.16.2, alongside datasets>=2.16.1, mmengine>=0.10.3, transformers>=4.37.2, peft>=0.8.1 and timm>=0.9.12, plus sentencepiece, tqdm, ujson and joblib. The package itself requires Python 3.10 or newer, and it exposes a console script named diffengine bound to diffengine:cli, which is the entry point that receives the train subcommand and the config name. If you follow the README literally you can end up with a PyTorch the manifest will not accept.

## diffusers is installed from one commit, not from a release

One dependency is not a version at all. Instead of pinning diffusers to a release, the manifest names the repository with a specific commit hash and an egg fragment, so the install resolves to that exact point in the library's history rather than to whatever is current. That is a deliberate choice for a training toolbox, since the training code is developed against a moving library and a release pin would break it, but it has consequences you should accept deliberately. Your environment is coupled to one upstream commit, pip has to reach git to complete the install, and the resolved diffusers version will not match what another tool in the same environment expects. Optional extras exist for the heavier paths, with a dev group of pytest and coverage, an optional group of ftfy, bs4, deepspeed and colossalai, and a docs group.

## The container builds xformers from source for two GPU architectures

There is a Dockerfile and a compose file, and both assume an NVIDIA machine with a GPU. The image starts from the NVIDIA PyTorch container tagged 24.01-py3, installs a working set of tools including git, tmux, the GitHub CLI, vim, a Mesa development library and zsh with a named theme, then copies the project and installs it. xformers is not taken from a wheel: ninja is installed, the CUDA architecture list is set to 8.6 and 9.0+PTX with a maximum of eight build jobs, and xformers is built from its git repository at tag 0.0.24. There is also an OpenCV fixup, where opencv is uninstalled, its cv2 directory under the Python 3.10 dist-packages is removed, and opencv-python-headless is installed instead, which is the usual remedy for a headless container that cannot load libGL.

## compose reserves a GPU and bind mounts the workspace over the image

The compose file has one service, named diffengine, built from the local directory, with the host working directory bind mounted to /workspace and the working directory set there as well, so the code you edit is the code that runs. Two settings there are deliberate. ipc: host shares the host's IPC namespace with the container, which is what lets data loader workers use shared memory rather than files, and the deploy block reserves a device with the gpu capability so the container is placed on a GPU. The environment adds PYTHONPATH pointing at /workspace, and the container runs with a tty allocated so interactive runs behave. There is also a .devcontainer directory at the top level, so the same assumption is available as a dev container for editors that support one.

## v1.0.0 landed in January 2024, and the last push was the next month

The release history is short: v0.2.1 on 2023-10-16, v0.3.0 on 2023-11-22 and v1.0.0 on 2024-01-10, with the manifest version matching that newest tag. The repository is not archived, sits on main, and was last pushed on 2024-02-18, so the final commit sits between releases rather than after one. The licence is Apache-2.0 and the package keywords are computer vision and diffusion models. Documentation lives on readthedocs with a get started page and a set of run guides covering Stable Diffusion, Stable Diffusion XL, DreamBooth, LoRA, ControlNet, the XL variants of each, IP Adapter and T2I Adapter, and there is a Colab notebook demonstrating training with the SD 1.5 and SD 2.1 DreamBooth configurations if you would rather not set up a GPU locally.

## Conclusion

DiffEngine suits someone who already knows how to fine-tune Stable Diffusion with diffusers and wants MMEngine's config discipline on top of it, since the run directory layout, the last_checkpoint marker and the adapter naming all line up with habits from that ecosystem. Three things to check before you start. diffusers is installed from one pinned git commit rather than a release, so your environment is tied to that commit until you change it yourself, and the README and the manifest disagree about the PyTorch floor, with one saying 2.0 and the other requiring 2.1.2. The container image builds xformers from source against specific CUDA architectures, which is slow and pins you to NVIDIA hardware. And the last push is dated 2024-02-18 with the newest tag v1.0.0 from January 2024, so check the current diffusers API before you assume the training code still runs as written.

## FAQ

### What is the best diff tool in this repository?

DiffEngine is not a diff tool. It is a Python toolbox for training diffusion models on top of diffusers and MMEngine, with pre-defined configs for Stable Diffusion, Stable Diffusion XL, DreamBooth and LoRA, and it does not compare or display differences between files.

### What is a diff file?

There is no such artefact here. What a training run produces is a work_dirs directory named after the config, containing a log file, a vis_data folder with JSON logs, a config copy and visualisations, an iter checkpoint, a last_checkpoint marker for resuming, and a step directory holding the adapter_config.json and adapter_model.bin files that diffusers.pipeline loads.

### What is code diff?

Nothing in DiffEngine concerns code diffing. The closest thing to a comparison is in its dependencies: diffusers is installed from a specific commit of its repository rather than from a release, so the library version is fixed to one point in its history rather than tracked against the latest release.

## Sources

- [Official README](https://github.com/okotaku/diffengine#readme)
- [Project repository](https://github.com/okotaku/diffengine)
- [Release notes](https://github.com/okotaku/diffengine/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/okotaku-diffengine
