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

Instructions for installing PyTorch #6409

Open
1 task done
davidgilbertson opened this issue Sep 5, 2022 · 140 comments
Open
1 task done

Instructions for installing PyTorch #6409

davidgilbertson opened this issue Sep 5, 2022 · 140 comments
Labels
area/docs Documentation issues/improvements status/triage This issue needs to be triaged

Comments

@davidgilbertson
Copy link

davidgilbertson commented Sep 5, 2022

  • I have searched the issues of this repo and believe that this is not a duplicate.

Issue

As mentioned in issue #4231 there is some confusion around installing PyTorch with CUDA but it is now somewhat resolved. It still requires a few steps, and all options have pretty serious flaws. Below are two options that 'worked' for me, on Poetry version 1.2.0.

Option 1 - wheel URLs for a specific platform

  • You will need to pick the specific wheels you want. These are listed here: https://download.pytorch.org/whl/torch_stable.html. E.g. if you want CUDA 11.6, Python 3.10 and Windows, search that page for cu116-cp310-cp310-win_amd64.whl to see the matches for torch, torchaudio and torchvision
  • In your pyproject.toml file add the URLs like:
[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.23.2"
torch = { url = "https://download.pytorch.org/whl/cu116/torch-1.12.1%2Bcu116-cp310-cp310-win_amd64.whl"}
torchaudio = { url = "https://download.pytorch.org/whl/cu116/torchaudio-0.12.1%2Bcu116-cp310-cp310-win_amd64.whl"}
torchvision = { url = "https://download.pytorch.org/whl/cu116/torchvision-0.13.1%2Bcu116-cp310-cp310-win_amd64.whl"}
  • Run poetry update. It will download a lot of data (many GB) and take quite some time. And this doesn't seem to cache reliably (at least, I've waited 30 minutes+ at 56 Mbps three separate times while troubleshooting this, for the exact same wheels)

Note that each subsequent poetry update will do another huge download and you'll see this message:

  • Updating torch (1.12.1+cu116 -> 1.12.1+cu116 https://download.pytorch.org/whl/cu116/torch-1.12.1%2Bcu116-cp310-cp310-win_amd64.whl)
  • Updating torchaudio (0.12.1+cu116 -> 0.12.1+cu116 https://download.pytorch.org/whl/cu116/torchaudio-0.12.1%2Bcu116-cp310-cp310-win_amd64.whl)
  • Updating torchvision (0.13.1+cu116 -> 0.13.1+cu116 https://download.pytorch.org/whl/cu116/torchvision-0.13.1%2Bcu116-cp310-cp310-win_amd64.whl)

Option 2 - alternate source

[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.23.2"
torch = { version = "1.12.1", source="torch"}
torchaudio = { version = "0.12.1", source="torch"}
torchvision = { version = "0.13.1", source="torch"}

[[tool.poetry.source]]
name = "torch"
url = "https://download.pytorch.org/whl/cu116"
secondary = true

This seems to have worked (although I already had the packages installed) but it reports errors like Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pillow/, but I think they get installed anyway (maybe a better message would be "Can't access pillow at 'https://download.pytorch.org/whl/cu116', falling back to pypi")

Also, if you later go on to do, say poetry add pandas (a completely unrelated library) you'll get a wall of messages like:

Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pandas/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pandas/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pytz/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/python-dateutil/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/numpy/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pillow/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/requests/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/typing-extensions/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/certifi/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/urllib3/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/idna/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/charset-normalizer/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/python-dateutil/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/six/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/pytz/
Source (torch): Authorization error accessing https://download.pytorch.org/whl/cu116/six/

This happens with or without secondary = true in the source config.

Maintainers: please feel free to edit the text of this if I've got something wrong.

@davidgilbertson davidgilbertson added area/docs Documentation issues/improvements status/triage This issue needs to be triaged labels Sep 5, 2022
@dimbleby
Copy link
Contributor

dimbleby commented Sep 5, 2022

Failure to cache during resolution is covered by #2415, poetry's insistence on checking all sources for all packages is discussed at #5984

@variolam
Copy link

variolam commented Sep 6, 2022

Solution 1 seems infeasible when working in a team with machines on different operating systems, due to the need of providing the complete URL of the wheel including operating system and exact version number.

Solution 2 seems to work, but it results in downloading every single PyTorch version that can found, independent on the operating system. I'm running Windows and the download looks like this:

image

A single installation takes around 15-20 minutes at ~250 Mbps.

@neersighted
Copy link
Member

Poetry will always download wheels for every platform when you install -- this is because there is no other way to get package metadata from a repository using PEP 503's API.

@Queuecumber
Copy link

Queuecumber commented Sep 6, 2022

Can you elaborate a little on what metadata is needed and why downloading every conceivable version of a package yields that metadata? As mentioned this leads to a ~20min install for one package

@radoering
Copy link
Member

Solution 1 seems infeasible when working in a team with machines on different operating systems, due to the need of providing the complete URL of the wheel including operating system and exact version number.

It's not convenient, but it should be feasible with multiple constraints dependencies.

@neersighted
Copy link
Member

neersighted commented Sep 6, 2022

Poetry requires the package's core metadata aka the METADATA file (most critically this includes dependencies), as well as the bdist/sdist itself for hashing purposes. Note that PEP 658 is a standard for serving the METADATA file that is implementable by third-party repositories, and PEP 691 specifies a (potentially) richer JSON API (including hashes) that third-party repositories could likely implement.

However, Poetry is unlikely to grow support for these new APIs until PyPI does, and I think third party repos are unlikely to implement it before PyPI. Eventually support for these APIs will allow for feature and performance parity in Poetry between PyPI and third-party repositories. Until then, we are stuck with the legacy HTML API, which requires us to download every package when generating a lock file for the first time.

After your cache is warm you will not need to download again, and on other platforms you will only download the necessary files as the metadata is captured in the lock file.

@Queuecumber
Copy link

What I'm not understanding is that poetry knows I'm on Linux with python 3.8 but it still downloads

https://download.pytorch.org/whl/cu116/torch-1.12.1%2Bcu116-cp37-cp37-win_amd64.whl

Or does that wheel not contain the core metadata that is needed?

@Queuecumber
Copy link

Queuecumber commented Sep 6, 2022

Also there seems to be a second problem going on here unless I've misunderstood the documentation

I have this in my pyproject.toml

[[tool.poetry.source]]
name = "torchcu116"
url = "https://download.pytorch.org/whl/cu116"
default = false
secondary = true

i.e. secondary = true

Yet poetry is asking that repository for every package I try to install. I thought from the documentation that secondary meant it would go to pypi for any package unless specifically asked to go to that custom repository.

@neersighted
Copy link
Member

What I'm not understanding is that poetry knows I'm on Linux with python 3.8 but it still downloads

https://download.pytorch.org/whl/cu116/torch-1.12.1%2Bcu116-cp37-cp37-win_amd64.whl

Or does that wheel not contain the core metadata that is needed?

Poetry constructs a universal lock file -- we write hashes to the lock file for all supported platforms. Thus on the first machine you generate a lock file, you will download a wheel for every supported platform. There is no way to write hashes to the lock file for those foreign/other platform versions without downloading them first.

If you want to reduce the scope of this a bit, you can tighten your Python constraint. There is a prototype of a new feature at #4956 (though it needs resurrection, design, and testing work) to add arbitrary markers to let a project reduce its supported platforms as an opt-in.

Also there seems to be a second problem going on here unless I've misunderstood the documentation

I have this in my pyproject.toml

[[tool.poetry.source]]
name = "torchcu116"
url = "https://download.pytorch.org/whl/cu116"
default = false
secondary = true

i.e. secondary = true

Yet poetry is asking that repository for every package I try to install. I thought from the documentation that secondary meant it would go to pypi for any package unless specifically asked to go to that custom repository.

I think it might be you misreading -- that is the intended and documented behavior. There is a proposal to introduce new repository types at #5984 (comment) as the current secondary behavior covers multiple use cases poorly, while being ideal for none of them.

@Queuecumber
Copy link

Queuecumber commented Sep 6, 2022

Poetry constructs a universal lock file

OK this makes sense now, thanks for the explanation, looking forward to that PR hopefully being merged eventually

I think it might be you misreading

I was misreading I see that this is intended behavior

the current secondary behavior covers multiple use cases poorly

I agree with that and I hope that these new repository types can be implemented

@ZetiMente
Copy link

Can't wait for option 2 to have good performance !

@neersighted
Copy link
Member

Please 👍 on issues instead of commenting me too -- it keeps the notifications down and still shows interest. Thanks!

RonMcKay added a commit to RonMcKay/UQGAN that referenced this issue Sep 30, 2022
Poetry is not yet ready to handle the different versions of PyTorch and
Torchvision. See the related issue:
python-poetry/poetry#6409
@voegtlel
Copy link

Probably a follow-up issue on the second option:
If I do poetry install on that, I get

Installing dependencies from lock file

Package operations: 50 installs, 0 updates, 0 removals

  • Installing wrapt (1.12.1): Failed

  KeyringLocked

  Failed to unlock the collection!

  at ~/.local/share/pypoetry/venv/lib/python3.10/site-packages/keyring/backends/SecretService.py:67 in get_preferred_collection
       63│             raise InitError("Failed to create the collection: %s." % e)
       64│         if collection.is_locked():
       65│             collection.unlock()
       66│             if collection.is_locked():  # User dismissed the prompt
    →  67│                 raise KeyringLocked("Failed to unlock the collection!")
       68│         return collection
       69│ 
       70│     def unlock(self, item):
       71│         if hasattr(item, 'unlock'):

I guess it tries to load that from the secondary repo as well, and expects to use the keyring due to the unauthorized thing?

@neersighted
Copy link
Member

That's #1917 -- our use of keyring hits surprisingly many system configurations in which hard errors occur, and it needs some work.

@felix-ht
Copy link

@neersighted at least PyPI seems have started work on the new json APi

@neersighted
Copy link
Member

Indeed, Poetry 1.2.2 relies on the new PEP 691 support. However, PEP 658 is the real blocker for better performance in third-party repos -- there is a long-running PR blocked on review and a rather combative contributor, but otherwise no major progress on that front.

@MaKaNu
Copy link
Contributor

MaKaNu commented Oct 20, 2022

could you add a link to the blocked PR? I switched today to method 1 because method 2 took ages. Seems the meta servers are slowed down today... Dependency resolving which takes up to 4000 seconds for method 1 is also insane. And then it failed because I accidental copied 1.12.0 instead of 1.12.1 for the windows release. I really like the idea of poetry but this needs huge improvement.

@felix-ht
Copy link

felix-ht commented Oct 20, 2022

We use neither these approaches.
My hacky solution to just install the base version of pytorch say 1.12.1 with poetry and then install the specific versions needed for the machines with pip in a makefile command.

As the gpu versions have the same dependencies as the base version this should be OK.

The big downsides are

  • download both torch versions
  • lockfile does not mach installed version (of pytorch)
  • a change in the pytorch version requires and update to the makefile as well as the pyproject.toml
  • any poetry action like poetry add will reinstall the base version
  • breaks Packaging - usually not a concern for ml projects

The big upside is that it is very easy to create make scripts for different machines - and that its pretty fast (very important for ci/cd)
Example:

[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.23.2"
torch = "1.12.1"
torchvision = "0.13.1"
install_cu116:
	poetry install
	poetry run pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 -f https://download.pytorch.org/whl/torch_stable.html

@timothyjlaurent
Copy link

install_cu116:
	poetry install
	poetry run pip install torch==1.12.1+cu116 torchvision==0.13.1+cu116 -f https://download.pytorch.org/whl/torch_stable.html

this has essentially been our approach, but in Dockerfiles, gated by a build arg

ARG TORCH_ARCH="cpu"
#ARG TORCH_ARCH="cu113"

RUN  poetry install -vvv --no-root --no-dev \
    && pip install -U wheel torch==1.12.1+${TORCH_ARCH} torchvision==0.13.1+${TORCH_ARCH} -f https://download.pytorch.org/whl/torch_stable.html \
    && pip uninstall poetry -y \
    && rm -rf ~/.config/pypoetry \
    && rm -rf /root/.cache/pip

This also allows installing the CPU version which is smaller a smaller package that lacks the CUDA drivers that come in the normal pytorch package from pypi. They help to slim the images down.

@brochier
Copy link

Hi ! Do you know if it's possible to specify two different optional versions of torch in the pyproject.toml ? I would like to use a cpu version locally and a gpu version on a distant server. You can have a look at an example in this stack overflow post.

@neersighted
Copy link
Member

That is something not unlike #5222; the consensus has been that as Poetry is an interoperable tool, no functionality will be added to the core project to support this until there is a standards-based method. A plugin can certainly support this with some creativity and would be the immediate "I want Poetry to support this" use case solution in my mind.

@robinbrochier
Copy link

#5222

Thanks for your answer, do you have any such plugin in mind ?

@neersighted
Copy link
Member

I don't have any links at hand, but building on top of Light the Torch has been discussed. But if you mean if I know anyone is working on one, no, not that I am aware of.

@arthur-st
Copy link

For as long as pip install torch does Just Work ™️, having to put any effort at all into installing torch via poetry will be a vote against using it in commercial ML work that requires torch or similar hardware-bound components. Assuming that one is open to consider poetry, conda, and pipenv as functionally equivalent options, of course.

@neersighted
Copy link
Member

I don't see that as a Poetry problem -- the issue is that there is an unmet packaging need, and no one from the ML world is working with the PyPA to define how to handle this robustly/no one from the PyPA has an interest in solving it.

Likewise, there is no interest in Poetry in supporting idiosyncratic workarounds for a non-standard and marginally compatible ecosystem; we'll be happy to implement whatever standards-based process evolves to handle these binary packages, but in the mean time any special-casing and package-specific functionality belong in a plugin and not Poetry itself.

@QuentinSoubeyranAqemia
Copy link

Edit: For some reason, doing multiple poetry install -E cuda --with cuda switches between the torch sources with every install. But it's a workaround I can live with for a while as long as the torch-cpu installation isn't bugged. Maybe someone will find a better solution from this.

This alternance is exactly what we are struggling with. The reason is that your markers filters are entirely ignored, see issue #7748 .
We also have this comment above that says the extra value in the markers fields is not what we believe, but I could find no documentation nor specification on what the value actually is, so I'm still fuzzy on that.

You could only dependency groups (the poetry-only mecanism), i.e. only use --with cpu or --with cuda and ditch extras entirely (since they don't work). This will work for a local environment, but if you want to release a package, it will not propagate to the wheel/sdist since groups are poetry-only. This will lead to heavy dependency duplications, since you have to write each torch downstream dependency twice, once per group.

@QuentinSoubeyranAqemia
Copy link

QuentinSoubeyranAqemia commented May 15, 2024

Summary of current status

All views below are my own understanding and I might have mis-understood something. If so, kindly tell me and i'll update this summary

What is possible regarding torch & poetry

  • Install torch from torch's repository: use the source flag, see original post, Option 2: alternate source
    • NOTE: the supplemental flag is deprecated now (this example is old), use priority=explicit (see doc)
  • Use any single hardware-flavor of torch: use the source flag, see original post, Option 2: alternate source
    • Of note, latest poetry 1.8.2 has large performance improvements against torch's repositories as it no longer downloads the full wheel if the repository supports partial downloads
  • Switch torch's hardware-flavor based on platform type: (using the platform environment markers) (see example)
  • Switch torch's hardware-flavor based on poetry groups, a poetry-only mechanism that only work in your dev environment for the current package.
    • This is quite involved and difficult (hard to maintain) last I tried
    • This only works in your own local, poetry-managed development environment. Any package/environment depending on your package (via dependencies, wheel install, local path install in a requirements.txt, ...) will never see the groups and thus the torch dependency. Groups are not extras and are poetry current-package-dev-env only
    • There is no example, people tried using a single group, or mixing extra and group, which doesn't quite work
    • Of note, this involved and requires also using extra specifiers. This is because poetry dependency resolution combines all group together and checks they are compatible. Without the extra, different source URL for the torch dependency cannot be fulfilled at the same time and are flagged as incompatible. Using the extra marker (which do not work at install time) does work during dependency resolution, and is indeed required so that only at most one single torch dep may be selected at the same time

What is not possible

  • Switch the hardware-flavor with an extra: only extras (as opposed to poetry groups) propagates to wheel/sdist format and downstream projects, because they are part of the python version spec. This is due to Extra marker is ignored in poetry install, but respected in pip install #7748 and possibly this comment that says the extra marker value is not what we think, but doesn't say what it actually is.
    • Poetry doesn't fullfill the extra filtering, and ends up cycling between torch hardware flavor at each install

Reasons

The fundamental problem is that torch hardware-flavor is defined by the source URL of the repository to fetch it from. There are no torch-cpu or torch-cuda packages, and no way in Python dependency specifiers or version specifiers to support such flavor change, which is why torch uses the local version identifier despite the spec saying:

Local version identifiers SHOULD NOT be used when publishing upstream projects to a public index server

and

local version labels MUST be ignored entirely when checking if candidate versions match a given version specifier

So we likely need a update of python's dependency and/or version specs to handle that.


This thread is becoming long, the above summary tries to gather all that was tried and is known, and make it easier to look for what you need, or see if your solution has already been described.

@shuvamg007
Copy link

shuvamg007 commented May 15, 2024

You could only dependency groups (the poetry-only mecanism), i.e. only use --with cpu or --with cuda and ditch extras entirely (since they don't work).

Interesting. I couldn't get it to work without extras at all. I think it's working, but there might be some bug that is making it difficult for poetry to resolve the dependencies properly. Also, having 2 groups doesn't work for me either. One of the requirements (i.e. cpu) needs to be in main dependency group for it to work.

Either ways, it's broken. But atleast I can maintain versioning of packages for the time being.

TL;DR Latest summary

@QuentinSoubeyranAqemia
Copy link

QuentinSoubeyranAqemia commented May 15, 2024

Thats because poetry dependency resolution includes all groups together and thus checks that all groups are compatible with each other, because you might require --with cpu --with cuda. Poetry has no notion of exclusive groups.

IIRC Two dependency with different source URL are deemed incompatible. During dependency resolution (as opposed to install), the solver seems to understand the extra marker, and when it merges the dependency together, it understood this is an "either, or" that doesn't cause an incompatibility.

Added that to the summary

@slashtechno
Copy link

Thats because poetry dependency resolution includes all groups together and thus checks that all groups are compatible with each other, because you might require --with cpu --with cuda. Poetry has no notion of exclusive groups.

IIRC Two dependency with different source URL are deemed incompatible. During dependency resolution (as opposed to install), the solver seems to understand the extra marker, and when it merges the dependency together, it understood this is an "either, or" that doesn't cause an incompatibility.

Added that to the summary

I imagine this would break poetry build due to no version of PyTorch being installed unless a dependency group is specified, no?

@QuentinSoubeyranAqemia
Copy link

It will make a non-functional wheel/sdist which depends on torch but does not declare that dependency, indeed.
Group only work in your local, poetry-management development environment and are not translated to the wheel/sdist. You cannot use groups with poetry build

You're right that the summary doesn't mention that either, it is an important caveat. Added that to the summary

@PyroGenesis
Copy link

What is possible regarding torch & poetry

  • Install torch from torch's repository: use the source flag, see original post, Option 2: alternate source
  • Use any single hardware-flavor of torch: use the source flag, see original post, Option 2: alternate source

Note that the secondary priority for sources is deprecated now. Personally I use the explicit priority to make sure it directly checks the pytorch index for torch rather than using it as a fallback.

[[tool.poetry.source]]
name = "pytorch-cuda"
url = "https://download.pytorch.org/whl/cu121"
priority = "explicit"

[tool.poetry.dependencies]
python = "~3.10"
torch = { version = "2.1.1+cu121", source = "pytorch-cuda" }

Also, another issue many users had was that poetry would download every wheel of a particular pytorch version to compute the hashes. The solution we currently have is to remind the pytorch devs to add hashes to their wheels if the index regresses again.

@slashtechno
Copy link

It will make a non-functional wheel/sdist which depends on torch but does not declare that dependency, indeed. Group only work in your local, poetry-management development environment and are not translated to the wheel/sdist. You cannot use groups with poetry build

You're right that the summary doesn't mention that either, it is an important caveat. Added that to the summary

Can the devs implement a fix for this? Or is this by-design?

@QuentinSoubeyranAqemia
Copy link

@slashtechno It's by design. The poetry build can only leverage what the python packaging specification permits, since its building wheel/sdist for tools other than poetry (e.g. pip). Groups are not part of the PyPA specification (only extras) and won't be understood by those downstream tools.

@PyroGenesis Thank you, I added a note regarding supplemental/priority in the summary. I missed that the example was so old.

@david-waterworth
Copy link

I don't know if it's already been proposed, but I'd like to see some sort of "build target" option (specifically for the non-package mode) which enabled some way of specifying mutually exclusive versions of the same package/group of packages (i.e. torch cpu/cuda/rocm, faiss cpu/gpu etc) based on some target flag.

It's a fairly common use case in ML, you often see multiple requirement.txt files depending on the users needs. A challenge is probably that downstream libraries like huggingface transformers require torch and that requirement can be met by any of the different torch wheels (i.e. cpu, cuda).

Without this I find myself getting painted into a corner with poetry (I know work 50:50 between a linux workstation with gpu, and an M3 MacBook and at the moment have to hack together a combination of installing some stuff with pip and the rest with poetry)

@QuentinSoubeyranAqemia
Copy link

QuentinSoubeyranAqemia commented May 29, 2024

@david-waterworth
For non-package mode, that looks like an additional feature for poetry's custom dependency groups when they are optional, to mark them as incompatible with another. I'd open a new issue/feature request and link to this discussion.

From my own testing, I think you can achieve this effect by marking all dependencies in a group with the extra != "other-group" environment marker, but I'm not quite sure, things are complicated at that point.


Now for your particular use-case of linux workstation and MacBook, this is already possible without the need for any flag: use environments markers (poetry doc), in particular the platform_system one.
Poetry lets you write this more easily by writing your dependency as a TOML object, see this documentation example which uses platform and source like you want in the second example.

As an additional note, I think the PyPI's version of torch does work when cuda is not available, it just runs on the cpu.

@david-waterworth
Copy link

david-waterworth commented May 30, 2024

@QuentinSoubeyranAqemia I've not had any luck with dependency groups and extra's - i.e. I get the same as #6409 (comment)

Thanks for the environment markers pointer, that should be useful. I'd still like to be able to conditionally install the CPU or GPU verison on linux as well though, I quite often have to switch between CPU or GPU docker images so most of my projects now use poetry for the base sagemaker/boto dependencies but the containers I build for ML pipelines all use requirements.txt

@QuentinSoubeyranAqemia
Copy link

Thanks for the environment markers pointer, that should be useful. I'd still like to be able to conditionally install the CPU or GPU verison on linux as well though

As detailed in the summary, this is currently not possible. This is a limitation of the python's packaging spec, it's not inherent to poetry. The best you can do to my knowledge is switch based on your platform.

Note that when exporting poetry-managed to requirements.txt using poetry-export, you can select poetry dependency groups as you please with --with and --without

@david-waterworth
Copy link

@QuentinSoubeyranAqemia that’s where I get frustrated with poetry - on the home page it’s advertised as “PYTHON PACKAGING AND DEPENDENCY MANAGEMENT MADE EASY” but in reality everything I’ve read in here indicates the focus is more or less only on packaging and the associated standards compliance - there’s a use case for dependency management without packaging which hopefully will see improved support over time.

I need to take a closer look at ‘poetry-export’ - it could be useful

@tfha
Copy link

tfha commented Jun 12, 2024

A well functioning solution for installing pytorch with cuda using poetry.
I have battled with this problem for a while as well. I just want to post the solution I have used, that seems to be stable without too many warnings, and which works when you install other dependencies, in a complex training session etc. Its basically similar to what @PyroGenesis has described. I just want to add the poetry commands and some extra info as well.

I use Ubuntu (WSL) and Python version 3.12. You find the url for the right wheels file from pytorch getting started. Here I use the cuda 12.1 version.

You first change the source for where poetry tries to find wheels for pytorch with:

poetry source add --priority=explicit pytorch https://download.pytorch.org/whl/cu121

Your pyproject.toml file will then be updated with this:

[tool.poetry.dependencies]
python = "^3.12"
torch = {version = "^2.3.1+cu121", source = "pytorch"}

[[tool.poetry.source]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"
priority = "explicit"

It is superimportant that the priority is set to explicit. This means that poetry will look for wheels in this source only if is requested explicitly by the name of the source, which I have set to "pytorch". All other packages will be installed from the standard pypi source, when you run poetry add <package> or poetry install.

You can then continue to install PyTorch with CUDA support by running the following command in the terminal:

poetry add torch --source pytorch

@shuvamg007
Copy link

shuvamg007 commented Jun 12, 2024

@QuentinSoubeyranAqemia that’s where I get frustrated with poetry - on the home page it’s advertised as “PYTHON PACKAGING AND DEPENDENCY MANAGEMENT MADE EASY” but in reality everything I’ve read in here indicates the focus is more or less only on packaging and the associated standards compliance - there’s a use case for dependency management without packaging which hopefully will see improved support over time.

I need to take a closer look at ‘poetry-export’ - it could be useful

@david-waterworth I have a similar use case wherein I use it for both packaging and dependency management. So while packaging doesn't work right now, it works pretty good for dependency management. I use the following config for example:

[tool.poetry]
name="<proj_name>"
...
readme="README.md"
package-mode=false

[tool.poetry.dependencies]
python = "~3.12"

[tool.poetry.group.cpu]
optional=true

[tool.poetry.group.cpu.dependencies]
torch={ version="~2.2", source="pytorch-cpu", markers="extra=='cpu' and extra!='cuda'" }
torchvision={ version="~0.17", source="pytorch-cpu", markers="extra=='cpu' and extra!='cuda'" }

[tool.poetry.group.cuda]
optional=true

[tool.poetry.group.cuda.dependencies]
torch={ version="~2.2", source="pytorch-cuda", markers="extra=='cuda' and extra!='cpu'" }
torchvision={ version="~0.17", source="pytorch-cuda", markers="extra=='cuda' and extra!='cpu'" }

[tool.poetry.extras]
cuda=["torch", "torchvision"]
cpu=["torch", "torchvision"]

[[tool.poetry.source]]
name="pytorch-cuda"
url="https://download.pytorch.org/whl/cu121"
priority="explicit"

[[tool.poetry.source]]
name="pytorch-cpu"
url="https://download.pytorch.org/whl/cpu"
priority="explicit"

You can no basically install with cpu, gpu or no dependency with poetry install -E cpu --with cpu, poetry install -E cuda --with cuda, and poetry install. Adding package-mode=false takes care of only dependency management. Note that this is with the latest poetry version (1.8.3) I have.

@AvailableHost
Copy link

AvailableHost commented Jun 14, 2024

Do anyone have Simple guide How to update everything (pip install torch, torch2.1.2+cu and whatever) for using SD XL and other model? (after deleting venv folder. When everything fuck's up im just reistall venv)
In my version stable diffusion (amd) every time im try to update SD i have exception
xformers requires torch 2.1.2 but have 1.13......
torchvision requires torch 2.0.0 but have but have 1.13......
...
All i need is 5 line what i need to install in cmd:
pip install torch....
pip install torchvision....
pip install protobuf<4.0...
image

@stf976
Copy link

stf976 commented Jun 18, 2024

@shuvamg007 For anyone still looking for a solution, the following hack worked for me on Poetry version 1.8.2:

With Poetry 1.8.3 this does not work. It just always installs the version from the [tool.poetry.dependencies] section (cpu flavor in this case).

@shuvamg007 Adding package-mode=false takes care of only dependency management. Note that this is with the latest poetry version (1.8.3) I have.

This does not work with poetry 1.8.3 either. With the given toml file (using Python 3.11), poetry install simply does not install any packages, regardless of the -E or --with options.

The lock file contains two [[package]] blocks for torchvision, one with the cpu flavor, and the other for cuda. The extras blocks looks like this.

[extras]
cpu = []
cuda = []

I am using Poetry installed from the installer (https://github.com/python-poetry/install.python-poetry.org) on Ubuntu 23.04. Could you please elaborate on what version you are using (OS, installer source)?

@lucaspar
Copy link

lucaspar commented Jun 18, 2024

@stf976 there's a slight variation of that pyproject.toml that works, but it's buried by other comments in this thread.

I've created this repo to help others find a setup that works for CPU and GPU installs. See if you find it useful.

@shuvamg007
Copy link

shuvamg007 commented Jun 18, 2024

I am using Poetry installed from the installer (https://github.com/python-poetry/install.python-poetry.org) on Ubuntu 23.04. Could you please elaborate on what version you are using (OS, installer source)?

Thanks for pointing this out. I just debugged and realized that there needs to be a dependency that needs to force torch to be installed. I'm not sure of this is a bug or not, but I don't have free time to actually debug this (commenting this from work). So as a workaround, I published a package to pypi that imposes this requirement. Please check the following code (hopefully it works):

[tool.poetry]
...
package-mode = false

[tool.poetry.dependencies]
python = "~3.12"

[tool.poetry.group.cpu]
optional=true

[tool.poetry.group.cpu.dependencies]
torch={ version="~2.2", source="pytorch-cpu", markers="extra=='cpu' and extra!='cuda'" }
torchvision={ version="~0.17", source="pytorch-cpu", markers="extra=='cpu' and extra!='cuda'" }
poetorch={ version="0.1.0", extras=["cpu", "vision"] }

[tool.poetry.group.cuda]
optional=true

[tool.poetry.group.cuda.dependencies]
torch={ version="~2.2", source="pytorch-cuda", markers="extra=='cuda' and extra!='cpu'" }
torchvision={ version="~0.17", source="pytorch-cuda", markers="extra=='cuda' and extra!='cpu'" }
poetorch={ version="0.1.0", extras=["cuda", "vision"] }

[tool.poetry.extras]
cuda=[]
cpu=[]

[[tool.poetry.source]]
name="pytorch-cuda"
url="https://download.pytorch.org/whl/cu121"
priority="explicit"

[[tool.poetry.source]]
name="pytorch-cpu"
url="https://download.pytorch.org/whl/cpu"
priority="explicit"

A few things of note:

  • Installation is as usual. You can install with cpu, gpu or no dependency with poetry install -E cpu --with cpu, poetry install -E cuda --with cuda, and poetry install respectively.
  • tool.poetry.extras itself doesn't need anything in it. The extras marker needs to exist though. So make sure it stays
  • The package poetorch has some extras mentioned in it. Depending on which installation you want, add that marker to extras (cpu or cuda). Since not everyone requires torchvision, that was added as an optional extra with the marker vision. Exclude that if you only require torch.
  • poetorch itself is just an empty project. All it does is add the dependency for torch and torchvision. There are some requirements (python>=3.8, torch==2.*, torchvision==0.*). I'll add the repository to github for reference later and update it here.

Hope this helps

@stf976
Copy link

stf976 commented Jun 20, 2024

Thanks for pointing this out. I just debugged and realized that there needs to be a dependency that needs to force torch to be installed. I'm not sure of this is a bug or not, but I don't have free time to actually debug this (commenting this from work). So as a workaround, I published a package to pypi that imposes this requirement. Please check the following code (hopefully it works):

With the additional package it works here too (tested with poetry 1.8.3), thanks a lot! It is now possible to switch between torch flavors and install the right packages using the --with cpu and --with cuda parameters.

I also tried it with newer versions of pytorch (torch-2.3.1 and torchvision-0.18.1), and that worked as well.

Unfortunately, poetry export -f requirements.txt --output requirements.txt always outputs the cuda torch packages, regardless of the -E and --with parameters. It does output the right poetorch package though, i.e. with [cpu] or [cuda] options. Using --only cpu or --without cuda doesn't help either. This appears to be a bug in poetry, as it should export only packages from the selected groups as far as I understand.

Overall it seems like a handy solution to the open issue, but it does not work with the current version of poetry in all cases.

@ZekunZh
Copy link

ZekunZh commented Jul 2, 2024

Inspired by the solution of @shuvamg007, I found another solution that I think is easier to read and understand.

The main idea is to specify only the versions of torch and torchvision in [tool.poetry.dependencies], and switch the source using poetry group and extras.

I tested the pyproject.toml using poetry of version 1.7.1 and version 1.8.3.

To install torch-cpu:

poetry install -E cpu --with cpu --sync

To install torch-gpu:

poetry install -E gpu --with gpu --sync

Hope this can help !

[tool.poetry]
...
package-mode = false

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.dependencies]
python = "^3.11"
torch = { version = "^2.2.1", optional = true }
torchvision = { version="^0.17.1", optional = true }

[tool.poetry.group.cpu]
optional = true

[tool.poetry.group.cpu.dependencies]
torch = { version = "^2.2.1", source = "torch_cpu", markers = "extra=='cpu' and extra!='gpu'" }
torchvision = { version="^0.17.1", source = "torch_cpu", markers = "extra=='cpu' and extra!='gpu'" }

[tool.poetry.group.gpu]
optional = true

[tool.poetry.group.gpu.dependencies]
torch = { version = "^2.2.1", source = "torch_cuda", markers = "extra=='gpu' and extra!='cpu'" }
torchvision = { version="^0.17.1", source = "torch_cuda", markers = "extra=='gpu' and extra!='cpu'" }


[tool.poetry.extras]
cpu = ["torch", "torchvision"]
gpu = ["torch", "torchvision"]

[[tool.poetry.source]]
name = "torch_cpu"
url = "https://download.pytorch.org/whl/cpu"
priority = "explicit"

[[tool.poetry.source]]
name = "torch_cuda"
url = "https://download.pytorch.org/whl/cu118"
priority = "explicit"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/docs Documentation issues/improvements status/triage This issue needs to be triaged
Projects
None yet
Development

No branches or pull requests