Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for disabling build isolation with uv sync #6607

Merged
merged 1 commit into from
Aug 26, 2024

Conversation

charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Aug 25, 2024

Summary

This requires some care, so worth documenting the intended workflows.

Closes #6437.

@charliermarsh charliermarsh added the documentation Improvements or additions to documentation label Aug 25, 2024
@charliermarsh charliermarsh requested a review from zanieb August 25, 2024 14:48
@kabouzeid
Copy link
Contributor

Maybe hold off on merging this; there are a couple of problems. Give me an hour or so, and I will provide you with an example.

@kabouzeid
Copy link
Contributor

kabouzeid commented Aug 25, 2024

First of all, the --no-build-isolation-package option doesn't work for me at all with any package, whether in uv pip install, uv add, or in pyproject.toml. However, this is a separate issue, so here I will just use --no-build-isolation instead.

I see the following issues with the provided example:

  1. It only works if uv.lock already exists and/or flash-attn is already cached. Otherwise, for some reason, uv always tries to build flash-attn during sync, even though it was not requested.
uv sync --extra build
⠴ flash-attn==2.6.3
error: Failed to download and build `flash-attn==2.6.3`
  Caused by: Build backend failed to determine extra requires with `build_wheel()` with exit status: 1
--- stdout:

--- stderr:
Traceback (most recent call last):
  File "<string>", line 14, in <module>
  File "/home/abou_zeid/.cache/uv/builds-v0/.tmpJtZIFU/lib/python3.12/site-packages/setuptools/build_meta.py", line 332, in get_requires_for_build_wheel
    return self._get_build_requires(config_settings, requirements=[])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/abou_zeid/.cache/uv/builds-v0/.tmpJtZIFU/lib/python3.12/site-packages/setuptools/build_meta.py", line 302, in _get_build_requires
    self.run_setup()
  File "/home/abou_zeid/.cache/uv/builds-v0/.tmpJtZIFU/lib/python3.12/site-packages/setuptools/build_meta.py", line 502, in run_setup
    super().run_setup(setup_script=setup_script)
  File "/home/abou_zeid/.cache/uv/builds-v0/.tmpJtZIFU/lib/python3.12/site-packages/setuptools/build_meta.py", line 318, in run_setup
    exec(code, locals())
  File "<string>", line 21, in <module>
ModuleNotFoundError: No module named 'torch'
---
  Caused by: This error likely indicates that flash-attn==2.6.3 depends on torch, but doesn't declare it as a build dependency. If flash-attn==2.6.3 is a first-party package, consider adding torch to its `build-system.requires`. Otherwise, `uv pip install torch` into the environment and re-run with `--no-build-isolation`.
  1. --no-build-isolation doesn't install any declared build dependencies. These dependencies also need to be installed to compile flash-attn. For flash-attn, this is just psutil. If the default hatchling build system is used, then hatchling and editables are also needed for building. Those are the dependencies that should go into the build group, as they are only required for building and can be removed afterwards.

  2. torch will almost always be a main dependency, which makes the example a bit confusing. To clarify: torch is also needed for building extensions, but you wouldn't want to remove torch after building the extension.


Putting all of this together, it should look more like this

[project]
name = "project"
version = "0.1.0"
description = "..."
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["torch"]  # torch is almost always a main dependency

[project.optional-dependencies]
build = [
    "psutil",
    # "editables",  # only needed if build system is hatchling
    # "hatchling",  # only needed if build system is hatchling
]
compile = ["flash-attn"]

[tool.uv]
no-build-isolation-package = ["flash-attn"]  # currently doesn't work. must be a bug.
$ uv sync --extra build  # installs torch + flash-attn build deps
$ uv sync --extra compile  # compiles flash-attn, removes build deps (but keeps torch)

Again, this doesn't actually work right now if uv.lock is not present, because in that case, uv tries to build (but not install) all extras, regardless. Also, since --no-build-isolation-package doesn't seem to be working currently, you would still need to pass --no-build-isolation for now.

@charliermarsh
Copy link
Member Author

That first issue is already fixed on main (#6605).

@charliermarsh
Copy link
Member Author

charliermarsh commented Aug 25, 2024

It only works if uv.lock already exists and/or flash-attn is already cached. Otherwise, for some reason, uv always tries to build flash-attn during sync, even though it was not requested.

This is expected and required. flash-attn ships as a source distribution, and only at Metadata-Version: 2.1, so you must ask the build backend for its dependencies per the spec -- which in turn requires that its build dependencies are already installed. There's really nothing we can do about this -- it's a problem with the package. They need to upgrade to Metadata-Version: 2.2.

The only way to get things working in this case would be to use the uv pip install hack to pre-populate the virtual environment.

I'll have to use a different example here.

@charliermarsh
Copy link
Member Author

--no-build-isolation doesn't install any declared build dependencies.

Correct, all sounds right to me.

@kabouzeid
Copy link
Contributor

This is expected and required. flash-attn ships as a source distribution, and only at Metadata-Version: 2.1, so you must ask the build backend for its dependencies per the spec -- which in turn requires that its build dependencies are already installed. There's really nothing we can do about this -- it's a problem with the package. They need to upgrade to Metadata-Version: 2.2.

Thank you for the explanation, TIL! It seems the lock file has to be compiled with respect to all extras at once, even if they aren't explicitly requested. This is because the extras can introduce additional constraints on the other dependencies, correct?


Somehow all torch extensions I looked at are Metadata-Version: 2.1, not sure why. Perhaps we should just use the steps to build the environment in the example then?

uv add torch
uv add --optional build psutil  # possibly also others such as editables, hatchling
uv add --optional compile flash-attn

Now that the lock file exists and is commited to the repo, the end user can just sync:

uv sync --extra build
uv sync --extra compile

Actually, it seems that in the first example above the lock file doesn't match the pyproject.toml without another lock or sync call after adding the packages (see #6614).

@charliermarsh
Copy link
Member Author

It seems the lock file has to be compiled with respect to all extras at once, even if they aren't explicitly requested. This is because the extras can introduce additional constraints on the other dependencies, correct?

Yeah that's right -- we have to make sure that the entire environment can be installed (including any extras) after locking, so we generate a single lock that tracks all extras, etc.

@charliermarsh
Copy link
Member Author

I'm sorry that you've been a test subject for all the build isolation stuff -- we only added it at the very end (to uv sync -- uv pip has had it for a long time) to unblock folks, but we always want (and still want) to come up with a totally different solution to the underlying problems. E.g., I'd prefer an API where you can define the build dependencies yourself, or similar, and then we install in order as a graph.

readme = "README.md"
requires-python = ">=3.12"
dependencies = ["flash-attn"]
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we repeat the no-build-isolation-package = ["flash-attn"] bit here? I was surprised it was omitted.

@charliermarsh charliermarsh enabled auto-merge (squash) August 26, 2024 18:20
@charliermarsh charliermarsh merged commit 486c984 into main Aug 26, 2024
46 checks passed
@charliermarsh charliermarsh deleted the charlie/build-docs branch August 26, 2024 18:21
@kabouzeid
Copy link
Contributor

I'm sorry that you've been a test subject for all the build isolation stuff -- we only added it at the very end (to uv sync -- uv pip has had it for a long time) to unblock folks, but we always want (and still want) to come up with a totally different solution to the underlying problems. E.g., I'd prefer an API where you can define the build dependencies yourself, or similar, and then we install in order as a graph.

No worries! I'm actually pretty happy that it's working at all with these kinds of dependencies. I've never gotten it to properly work with any tool other than pip.

I totally agree that to really solve this, we need to tackle the actual underlying problems. It's super exciting that this is on the roadmap! I'm keeping a close eye on the project and will provide feedback on how these future APIs handle tricky cases like PyTorch and CUDA extensions. Thanks for all the great work you're doing!

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 28, 2024
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.3.2` -> `0.3.5` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.3.5`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#035)

[Compare Source](astral-sh/uv@0.3.4...0.3.5)

##### Enhancements

-   Add support for `--allow-insecure-host` (aliased to `--trusted-host`) ([#&#8203;6591](astral-sh/uv#6591))
-   Read requirements from `requires.txt` when available ([#&#8203;6655](astral-sh/uv#6655))
-   Respect `tool.uv.environments` in `pip compile --universal` ([#&#8203;6663](astral-sh/uv#6663))
-   Use relative paths by default in `uv add` ([#&#8203;6686](astral-sh/uv#6686))
-   Improve messages for empty solves and installs ([#&#8203;6588](astral-sh/uv#6588))

##### Bug fixes

-   Avoid reusing state across tool upgrades ([#&#8203;6660](astral-sh/uv#6660))
-   Detect musl and error for musl Python builds ([#&#8203;6643](astral-sh/uv#6643))
-   Ignore `send` errors in installer ([#&#8203;6667](astral-sh/uv#6667))

##### Documentation

-   Add development section to Docker guide and reference new example project ([#&#8203;6666](astral-sh/uv#6666))
-   Add docs for `constraint-dependencies` and `override-dependencies` ([#&#8203;6596](astral-sh/uv#6596))
-   Clarify package priority order in pip compatibility guide ([#&#8203;6619](astral-sh/uv#6619))
-   Fix docs for disabling build isolation with `uv sync` ([#&#8203;6674](astral-sh/uv#6674))
-   Improve consistency of directory lookup instructions in Docker ([#&#8203;6665](astral-sh/uv#6665))
-   Improve lockfile concept documentation, add coverage for upgrades ([#&#8203;6698](astral-sh/uv#6698))
-   Shift the order of some of the Docker guide content ([#&#8203;6664](astral-sh/uv#6664))
-   Use `python` to highlight requirements and use more content tabs ([#&#8203;6549](astral-sh/uv#6549))

### [`v0.3.4`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#034)

[Compare Source](astral-sh/uv@0.3.3...0.3.4)

##### CLI

-   Show `--editable` on the `uv add` CLI ([#&#8203;6608](astral-sh/uv#6608))
-   Add `--refresh` to `tool run` warning for `--with` dependencies ([#&#8203;6609](astral-sh/uv#6609))

##### Bug fixes

-   Allow per dependency build isolation for `setup.py`-based projects ([#&#8203;6517](astral-sh/uv#6517))
-   Avoid un-strict syncing by-default for build isolation ([#&#8203;6606](astral-sh/uv#6606))
-   Respect `--no-build-isolation-package` in `uv sync` ([#&#8203;6605](astral-sh/uv#6605))
-   Respect extras and markers on virtual dev dependencies ([#&#8203;6620](astral-sh/uv#6620))
-   Support PEP 723 scripts in GUI files ([#&#8203;6611](astral-sh/uv#6611))
-   Update lockfile after setting minimum bounds in `uv add` ([#&#8203;6618](astral-sh/uv#6618))
-   Use relative paths for `--find-links` and local registries ([#&#8203;6566](astral-sh/uv#6566))
-   Use separate types to represent raw vs. resolver markers ([#&#8203;6646](astral-sh/uv#6646))
-   Parse wheels `WHEEL` and `METADATA` files as email messages ([#&#8203;6616](astral-sh/uv#6616))
-   Support unquoted hrefs in `--find-links` and other HTML sources ([#&#8203;6622](astral-sh/uv#6622))
-   Don't canonicalize paths to user requirements ([#&#8203;6560](astral-sh/uv#6560))

##### Documentation

-   Add FastAPI guide to overview ([#&#8203;6603](astral-sh/uv#6603))
-   Add docs for disabling build isolation with `uv sync` ([#&#8203;6607](astral-sh/uv#6607))
-   Add example of reading script from stdin using echo ([#&#8203;6567](astral-sh/uv#6567))
-   Add tip to use intermediate layers in Docker builds ([#&#8203;6650](astral-sh/uv#6650))
-   Clarify need to include `pyproject.toml` with `--no-install-project` ([#&#8203;6581](astral-sh/uv#6581))
-   Move `WORKDIR` directive in Docker examples ([#&#8203;6652](astral-sh/uv#6652))
-   Remove duplicate `WORKDIR` directive in Docker example ([#&#8203;6651](astral-sh/uv#6651))

### [`v0.3.3`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#033)

[Compare Source](astral-sh/uv@0.3.2...0.3.3)

##### Enhancements

-   Add `uv sync --no-install-project` to skip installation of the project ([#&#8203;6538](astral-sh/uv#6538))
-   Add `uv sync --no-install-workspace` to skip installation of all workspace members ([#&#8203;6539](astral-sh/uv#6539))
-   Add `uv sync --no-install-package` to skip installation of specific packages ([#&#8203;6540](astral-sh/uv#6540))
-   Show previous version in self update message ([#&#8203;6473](astral-sh/uv#6473))

##### CLI

-   Add `--no-project` alias for `uv python pin --no-workspace` ([#&#8203;6514](astral-sh/uv#6514))
-   Ignore `.python-version` files in `uv venv` with `--no-config` ([#&#8203;6513](astral-sh/uv#6513))
-   Include virtual environment interpreters in `uv python find` ([#&#8203;6521](astral-sh/uv#6521))
-   Respect `-` as stdin channel for `uv run` ([#&#8203;6481](astral-sh/uv#6481))
-   Revert changes to pyproject.toml when sync fails duing `uv add` ([#&#8203;6526](astral-sh/uv#6526))

##### Configuration

-   Add `UV_COMPILE_BYTECODE` environment variable ([#&#8203;6530](astral-sh/uv#6530))

##### Bug fixes

-   Set `VIRTUAL_ENV` for `uv run` invocations ([#&#8203;6543](astral-sh/uv#6543))
-   Ignore errors in workspace discovery with `--no-project` ([#&#8203;6554](astral-sh/uv#6554))

##### Documentation

-   Add documentation for `uv python find` ([#&#8203;6527](astral-sh/uv#6527))
-   Add uv tool install example in Docker ([#&#8203;6547](astral-sh/uv#6547))
-   Document why we do lower bounds ([#&#8203;6516](astral-sh/uv#6516))
-   Fix to miss string termination in PowerShell commands for shell autocompletion documentation ([#&#8203;6491](astral-sh/uv#6491))
-   Fix incorrect workspace members keyword ([#&#8203;6502](astral-sh/uv#6502))
-   Use proper environment variables for Windows ([#&#8203;6433](astral-sh/uv#6433))
-   Improve caveat in `uvx` note ([#&#8203;6546](astral-sh/uv#6546))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support flash attention flash-attn --no-build-isolation with uv sync
3 participants