.. Adapting from https://docs.sglang.ai/references/contribution_guide.html

Contribution Guide
==================

Welcome to **Nunchaku**! We appreciate your interest in contributing.
This guide outlines how to set up your environment, run tests, and submit a Pull Request (PR).
Whether you're fixing a minor bug or implementing a major feature, we encourage you to
follow these steps for a smooth and efficient contribution process.

🚀 Setting Up & Building from Source
------------------------------------

1. Fork and Clone the Repository

   .. note::

      As a new contributor, you won't have write access to the `Nunchaku repository <github_nunchaku_>`_.
      Please fork the repository to your own GitHub account, then clone your fork locally:

   .. code-block:: shell

      git clone https://github.com/<your_username>/nunchaku.git

2. Install Dependencies & Build

   To set up your development environment, follow the steps in :ref:`Installation <build-from-source>`.
   Be sure to install all development dependencies by running:

   .. code-block:: shell

      pip install -e ".[dev]"

🧹 Code Formatting with Pre-Commit
----------------------------------

We use `pre-commit <https://pre-commit.com/>`__ hooks to maintain consistent code style across the project.
Before submitting your changes, please ensure pre-commit is installed and run:

.. code-block:: shell

   pip install pre-commit  # This should already be installed with the development dependencies
   pre-commit install
   pre-commit run --all-files

- ``pre-commit run --all-files`` manually triggers all checks and automatically fixes issues where possible.
  If it fails initially, re-run until all checks pass.

- ✅ **Ensure your code passes all checks before opening a PR.**

- 🚫 **Do not commit directly to the** ``main`` **branch.**
- Always create a feature branch (e.g., ``feat/my-new-feature``),
- commit your changes there, and open a PR from that branch.

🧪 Running Unit Tests & Integrating with CI
-------------------------------------------

Nunchaku uses ``pytest`` for unit testing. If you're adding a new feature,
please include corresponding test cases in the ``tests`` directory.
**Please avoid modifying existing tests.**

Running the Tests
~~~~~~~~~~~~~~~~~

.. code-block:: shell

   HF_TOKEN=$YOUR_HF_TOKEN pytest -v tests/flux/test_flux_examples.py
   HF_TOKEN=$YOUR_HF_TOKEN python .github/workflows/run_all_tests.py

.. note::

   ``$YOUR_HF_TOKEN`` refers to your Hugging Face access token,
   required to download models and datasets.
   You can create one at https://huggingface.co/settings/tokens.
   If you've already logged in using ``huggingface-cli login``,
   you can skip setting this environment variable.

Some tests generate images using the original 16-bit models.
You can cache these results to speed up future test runs by setting the environment variable ``NUNCHAKU_TEST_CACHE_ROOT``. If not set, the images will be saved in ``test_results/ref``.

Writing Tests
~~~~~~~~~~~~~

When adding a new feature,
please include corresponding test cases in the ``tests`` directory.
**Please avoid modifying existing tests.**

To test visual output correctness, you can:

1. **Generate reference images:**
   Use the original 16-bit model to produce a small number of reference images (e.g., 4).

2. **Generate comparison images:**
   Run your method using the **same inputs and seeds** to ensure deterministic outputs.
   You can control the seed by setting the ``generator`` parameter in the diffusers pipeline.

3. **Compute similarity:**
   Evaluate the similarity between your outputs and the reference images
   using the `LPIPS <https://arxiv.org/abs/1801.03924>`_ metric.
   Use the ``compute_lpips`` function provided in `tests/flux/utils.py <https://github.com/nunchaku-tech/nunchaku/blob/main/tests/flux/utils.py>`_:

   .. code-block:: python

      lpips = compute_lpips(dir1, dir2)

   - ``dir1``: Directory containing the reference images.
   - ``dir2``: Directory containing the images generated by your method.

**Setting the LPIPS Threshold**

To pass the test, the LPIPS score should be **below a predefined threshold**—typically **< 0.3**.

- First, run the comparison locally to observe the LPIPS value.
- Set the threshold slightly above your observed value to accommodate minor variations
  (a margin of **+0.04** is generally sufficient).
- Note that, due to the small sample size, slight fluctuations are expected.

By following these guidelines, you help maintain the reliability and reproducibility of Nunchaku’s test suite.
