Commit 8e09ed2
authored
Stop the curriculum schedule starting below min_difficulty (#8334)
## Symptom
The curriculum schedule can start below the `min_difficulty` it is
configured with, and for one pair the tutorial itself recommends it
starts at **0**.
```python
from deepspeed.runtime.data_pipeline.curriculum_scheduler import CurriculumScheduler
def sched(min_d, step):
return CurriculumScheduler({
"min_difficulty": min_d, "max_difficulty": 1024, "schedule_type": "fixed_linear",
"schedule_config": {"total_curriculum_step": 100, "difficulty_step": step},
})
for min_d, step in [(8, 8), (8, 16), (64, 16), (1, 8), (10, 8)]:
s = sched(min_d, step)
print(min_d, step, [s.get_difficulty(i) for i in range(6)])
```
| `min_difficulty` | `difficulty_step` | first six steps |
| --- | --- | --- |
| 8 | 8 | `[8, 16, 24, 32, 48, 56]` |
| **8** | **16** | **`[0, 16, 16, 32, 48, 48]`** |
| 64 | 16 | `[64, 64, 80, 80, 96, 112]` |
| **1** | **8** | **`[0, 8, 16, 24, 40, 48]`** |
| **10** | **8** | **`[8, 16, 24, 40, 48, 56]`** |
`min_difficulty=8` with `difficulty_step=16` is not a contrived pair.
The tutorial recommends "starting with `min_difficulty` at 8
(million-scale models) or 64 (billion-scale models)" and separately "we
usually set [`difficulty_step`] to 8 (for FP16 data) or 16 (for INT8
data)". A million-scale model on INT8 data lands on exactly that
combination, and its first training step gets a sequence length of 0.
## Root cause
`__fixed_root_get_difficulty`, which serves both `fixed_linear` (root
degree 1) and `fixed_root`, floors the interpolated value to a multiple
of `difficulty_step` and then clamps only the top:
```python
next_difficulty -= (next_difficulty % s_state[CURRICULUM_LEARNING_SCHEDULE_DIFFICULTY_STEP])
next_difficulty = min(next_difficulty, self.state[CURRICULUM_LEARNING_MAX_DIFFICULTY])
```
At step 0 the interpolation is exactly `min_difficulty`, so the floor
subtracts `min_difficulty % difficulty_step` and there is nothing to
stop it going under. The tutorial's own formula for this schedule is
`((step/total)**(1/root_degree)) * (max_difficulty - min_difficulty) +
min_difficulty`, which starts at `min_difficulty`.
## Fix
Clamp the bottom the way the top already is, one line.
This does not introduce a new exception to the "difficulty is a multiple
of `difficulty_step`" rule: the existing top clamp already returns
`max_difficulty` verbatim when it is not a multiple. With
`max_difficulty=1000` and `difficulty_step=16` the schedule returns
1000, not 992, once it runs out. Both endpoints being the configured
values rather than multiples of the step is the behaviour this function
already has at one end.
`__fixed_discrete_get_difficulty` picks from an explicit list and is
untouched.
## Test
Two tests in `tests/unit/runtime/test_data_efficiency.py`, both plain
CPU tests rather than `DistributedTest`, since `CurriculumScheduler`
needs neither an accelerator nor a process group:
- `test_curriculum_never_starts_below_min_difficulty`, parametrized over
`fixed_linear` and `fixed_root` and over five `(min_difficulty,
difficulty_step)` pairs including the tutorial's own recommendations,
checks the first twenty steps stay within `[min_difficulty,
max_difficulty]`.
- `test_curriculum_endpoints_are_the_configured_values` pins both ends
with a `max_difficulty` that is not a multiple of `difficulty_step`. Its
top-end assertion passes on master too, which is what makes it the
control for the argument above.
Against master: **7 failed, 4 passed, 6 skipped** (`assert 0 >= 8`,
`assert 8 >= 10`, `assert 0 == 8`). With the fix: **11 passed, 6
skipped**. The 6 skipped are the file's pre-existing `DistributedTest`
cases, which need 2 GPUs; a pristine checkout reports the same 6 skips
and nothing else.
yapf and flake8 clean, with yapf making no changes to either file.
---------
Signed-off-by: Vineeth Sai <vineethsai4444@gmail.com>1 parent c7eed15 commit 8e09ed2
2 files changed
Lines changed: 58 additions & 0 deletions
File tree
- deepspeed/runtime/data_pipeline
- tests/unit/runtime
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
140 | 149 | | |
141 | 150 | | |
142 | 151 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
53 | 102 | | |
54 | 103 | | |
55 | 104 | | |
| |||
0 commit comments