Skip to content

Conversation

@Xaenalt
Copy link

@Xaenalt Xaenalt commented Feb 6, 2026

This happens due to an unfortuante way that TensorFlow is built. Since it uses Bazel to build and package the wheel, it doesn't have the usual infrastructure one uses to build variant wheels. Due to that, a single repo is used to build wheels with different names. In Fromager's case, this means we specify the req as tensorflow but in reality will get tensorflow_cpu or tensorflow_rocm, etc. This is how they create them upstream, and to match the requirements from notebooks that the wheel naming convention remains the same, we have to override the check that the wheel name matches the req in extract_info_from_wheel_file().

To achieve this, I made it overridable like other functions and provided a default_extract_info_from_wheel_file() implemetation to preserve existing behavior. I expect TensorFlow will be one of the only users of this override.

@Xaenalt Xaenalt requested a review from a team as a code owner February 6, 2026 22:46
@Xaenalt Xaenalt force-pushed the AIPCC-10079 branch 4 times, most recently from 90ea79e to 95cf4ec Compare February 6, 2026 23:08
This happens due to an unfortuante way that TensorFlow is built. Since
it uses Bazel to build and package the wheel, it doesn't have the usual
infrastructure one uses to build variant wheels. Due to that, a single
repo is used to build wheels with different names. In Fromager's case,
this means we specify the req as `tensorflow` but in reality will get
`tensorflow_cpu` or `tensorflow_rocm`, etc. This is how they create them
upstream, and to match the requirements from notebooks that the wheel
naming convention remains the same, we have to override the check that
the wheel name matches the req in extract_info_from_wheel_file().

To achieve this, I made it overridable like other functions and provided
a default_extract_info_from_wheel_file() implemetation to preserve
existing behavior. I expect TensorFlow will be one of the only users of
this override.

Signed-off-by: Sean Pryor <[email protected]>
return (dist_name, dist_version, build_tag, wheel_tags)


def extract_info_from_wheel_file(
Copy link
Contributor

Choose a reason for hiding this comment

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

can we have tests?

Copy link
Author

Choose a reason for hiding this comment

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

Yes

Copy link
Collaborator

@tiran tiran left a comment

Choose a reason for hiding this comment

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

We have multiple packages that build different distributions from the same sources:

  • tensorflow (CUDA, CPU, ROCm)
  • cupy-cuda (12x, 13x)
  • opencv-python (currently we build only headless)

How does this PR address the problem that users request tensorflow-cpu or tensorflow-rocm in their requirements?

@Xaenalt
Copy link
Author

Xaenalt commented Feb 7, 2026

In this case, the req tensorflow builds tensorflow-cpu, tensorflow, tensorflow-rocm, but because the req doesn't match the filename, it fails that sanity check. The other option I can try is to create package plugins for tensorflow_cpu and tensorflow_rocm and have them reuse the code in tensorflow, but I didn't want to duplicate a lot of logic when there was a simpler way. If that's the preferred approach I can do that though

@dhellmann
Copy link
Member

It looks to me like the original function was mixing concerns. Extracting the info and validating it are two different things. If we split those, I think it would be more obvious that we need either a validation hook or, better, a config option for the expected wheel name to use in the core validation function.

@tiran
Copy link
Collaborator

tiran commented Feb 8, 2026

In this case, the req tensorflow builds tensorflow-cpu, tensorflow, tensorflow-rocm, but because the req doesn't match the filename, it fails that sanity check.

Typically, our users are expecting the same behavior as with pip/uv and same names as on upstream PyPI. They will have tensorflow-cpu in their requirements.txt for CPU variant.

The other option I can try is to create package plugins for tensorflow_cpu and tensorflow_rocm and have them reuse the code in tensorflow, but I didn't want to duplicate a lot of logic when there was a simpler way. If that's the preferred approach I can do that though

We could add an option to tell Fromager that tensorflow_cpu is an alias for tensorflow, so plugin or config setting for tensorflow also applies to tensorflow_cpu. Maybe we can get by with symlinks and re-use of override plugins?

$ ln -sr overrides/settings/tensorflow.yaml overrides/settings/tensorflow_cpu.yaml
$ ln -sr overrides/settings/tensorflow.yaml overrides/settings/tensorflow_rocm.yaml
[project.entry-points."fromager.project_overrides"]
tensorflow = "package_plugins.tensorflow"
tensorflow_cpu = "package_plugins.tensorflow"
tensorflow_rocm = "package_plugins.tensorflow"

Our downstream linter will not accept tensorflow_cpu = "package_plugins.tensorflow", but that is easy to fix.

@Xaenalt
Copy link
Author

Xaenalt commented Feb 9, 2026

Oh! That'd be perfect, that'd even simplify the other patch too

@Xaenalt Xaenalt closed this Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants