Repository navigation
Description
The problem
We have two contradictory positions on the same question live in the repo right now, and no way to tell which one applies.
Every dependency floor bump so far has been feature-driven, with the required feature named: datasets>=4.7.0 for the Json dtype (#5376), kernels>=0.14.0 for trust_remote_code, vllm>=0.11.0 (#5443). In #6447 I made that explicit for bitsandbytes: "Do not bump the floor solely to drop this filter: wait for an independent reason to require 0.50.0."
#7102 raises the peft floor on a different rationale: the floor should be no older than two years. That is a reasonable rule, and it is not the rule in #6447.
Meanwhile #6893 raises the bitsandbytes floor to drop a warning filter, which is exactly what #6447 says not to do and exactly what #7102's rationale would allow. It has been open for two weeks. There is no way to resolve it in either direction, because there is nothing to point at.
Why an explicit criterion
- Contributors cannot tell in advance whether the work is wanted. Require bitsandbytes>=0.50.0 and drop the _check_is_size warning filterย #6893 is defensible under one of our positions and refused under the other. That is not the contributor's mistake, there was nothing for them to read before they started.
- Any maintainer should be able to review one of these. Without a stated rule, a floor bump needs a judgment call rather than a check, so it queues behind whoever is presumed to hold the position instead of being reviewable by whoever picks it up. A criterion makes it verifiable from the diff.
- The floor is a public promise. It is what users install against, so deciding it case by case means it drifts in whichever direction the most recent PR argued.
Prior art
- SPEC 0 (scientific-python.org), which superseded NEP 29, recommends dropping support for dependency releases older than 24 months and Python releases older than 36 months. Calendar-driven and predictable. This is essentially the rationale in Require peft>=0.13.0 and drop the 0.12 version guardsย #7102.
- transformers itself has no time-based policy. Tightly coupled cores get narrow ranges with upper bounds (
huggingface-hub>=1.5.0,<2.0,tokenizers>=0.23.1,<0.24.0), and everything else gets an oldest-that-works floor that is left alone for years (accelerate>=1.1.0,numpy>=1.17). peft and accelerate behave the same way.
TRL sits closer to the transformers pattern, since we are a thin downstream of fast-moving libraries. But unlike transformers we carry a lot of in-tree version guards and compatibility shims, each with a known expiry, so the question of when a floor may rise comes up for us far more often than it does for them.
Proposal
Two separate questions. I have a suggested answer for each, but the point of this issue is to agree on something, not to argue for these specifically.
1. When is a bump justified at all?
Any one of these is sufficient, and the PR body says which one applies:
- Feature needed. TRL requires an API that only exists from that version. This is our current precedent.
- Cleanup. The bump deletes version guards or compatibility shims, and the target release is at least 6 months old. This is the case Remove bitsandbytes
_check_is_sizewarning filter once the minimum required bitsandbytes is >= 0.50.0ย #6447 currently refuses and Require peft>=0.13.0 and drop the 0.12 version guardsย #7102 relies on, so it is the one we most need to settle. - Staleness. The floor is older than 24 months, per SPEC 0. Then it may rise to the newest version that deletes something, without further justification.
2. Guard or bump?
Proposal: guarding is the default, and a bump has to be argued on what it deletes.
Version guards exist precisely so the floor can stay low while newer features light up only on newer installs. Adding a guard is not a user-visible break; raising a floor is. So when TRL wants to use an API newer than the floor, the first answer is a guard, and a floor bump needs its own justification under question 1 rather than being presented as the fix.
The counterweight, which is why this is a trade-off and not a one-liner: a guard is only worth writing when the older version keeps working with reduced capability, rather than the guard merely producing a nicer error. And because trainers here are self-contained by design, a guard inside a trainer block is not one guard, it is a dozen copies that then have to stay aligned. So "always guard" is not free either.
Open points
- The two numbers: is 6 months the right bar for a cleanup bump, and do we accept 24 months for staleness, or do we want to be more conservative than SPEC 0 given how fast our dependencies move?
- Is staleness alone enough, or must a stale floor also delete something to be worth touching?
- Does the same rule apply to optional extras (deepspeed, vllm, bitsandbytes, liger) as to the core dependencies, where the blast radius is different?
- Does experimental code get the same treatment as main code?
What agreeing on this unblocks
#6893 gets a yes or a no on its merits rather than on which maintainer looks at it. Future bumps of this kind become reviewable by anyone. And we stop re-deriving the same argument in each PR thread.
cc @huggingface/trl
Activity
qgallouedec commentedon Sep 8, 2026
Thanks for opening the discussion on this. IMO it's hard to write one rule that fits every dependency, but let's try.
So:
So the question is not "does this bump delete something", it's "what does the old version cost us, and who pays if we drop it".
How it materializes:
For the two open PRs:
One gap: bitsandbytes has no floor at all right now, we should add one I think
@albertvillanova you suggested 6 month, I think it's too short, 2 years is arbitrary, happy to target 1.5 years instead, but I feel like everything below 1 year is too fast.
albertvillanova commentedon Sep 8, 2026
Agreed on the cost model, and your reframe is better than mine.
On the 6 months I explained it badly: it was not an alternative to the 2 years, nor a permission to drop. It was an extra condition on your second case: under 2 years and the target release older than 6 months. The two answer different questions:
So it only ever blocks a bump, never licenses one: below the minimum we don't bump, between it and 2 years your balance decides. Same for your first case.
The only number in dispute is that minimum, and 1 year works for me.
#6893: agreed, no. bitsandbytes: agreed, and declaring a first floor drops support for nothing, so it needn't wait on #6893.
qgallouedec commentedon Oct 1, 2026
Agreed, thanks. So, for core dependencies:
Note that we already broke the last one: datasets>=4.7.0 (#5376) is from March 2026, 7 months old today.
Could you put all that in a short section of CONTRIBUTING.md so we can point to it? Then we can close this.