(device, module, dtype)
| 242 | @pytest.mark.parametrize("module", module_dict.values(), ids=module_dict.keys()) |
| 243 | @pytest.mark.parametrize("dtype", [torch.float16, torch.bfloat16]) |
| 244 | def test_kbit_backprop(device, module, dtype): |
| 245 | b = 16 |
| 246 | dim1 = 36 |
| 247 | dim2 = 84 |
| 248 | # dim1 = 37 |
| 249 | # dim2 = 83 |
| 250 | |
| 251 | ref = nn.Sequential(*[torch.nn.Linear(dim1, dim2), torch.nn.Linear(dim2, 128)]) |
| 252 | torch.nn.init.kaiming_normal_(ref[0].weight) |
| 253 | torch.nn.init.kaiming_normal_(ref[1].weight) |
| 254 | ref[1].weight.requires_grad_(False) |
| 255 | |
| 256 | kbit = nn.Sequential(*[torch.nn.Linear(dim1, dim2), module(dim2, 128)]) |
| 257 | |
| 258 | if ( |
| 259 | device == "hpu" |
| 260 | and isinstance(kbit[1], bnb.nn.Linear4bit) |
| 261 | and not is_supported_on_hpu(kbit[1].weight.quant_type, dtype) |
| 262 | ): |
| 263 | pytest.skip("This configuration not supported on HPU") |
| 264 | |
| 265 | kbit[0].weight.detach().copy_(ref[0].weight) |
| 266 | kbit[1].weight.detach().copy_(ref[1].weight) |
| 267 | kbit[0].bias.detach().copy_(ref[0].bias) |
| 268 | kbit[1].bias.detach().copy_(ref[1].bias) |
| 269 | kbit[1].weight.requires_grad_(False) |
| 270 | ref = ref.to(device=device, dtype=dtype) |
| 271 | kbit = kbit.to(device=device, dtype=dtype) |
| 272 | kbit = kbit.to(device=device, dtype=dtype) |
| 273 | |
| 274 | errs1 = [] |
| 275 | errs2 = [] |
| 276 | relerrs1 = [] |
| 277 | relerrs2 = [] |
| 278 | for i in range(100): |
| 279 | batch = torch.randn(b, dim1, device=device, dtype=dtype) |
| 280 | out1 = ref(batch) |
| 281 | out2 = kbit(batch) |
| 282 | out1.mean().backward() |
| 283 | out2.mean().backward() |
| 284 | |
| 285 | grad1 = ref[0].weight.grad |
| 286 | grad2 = kbit[0].weight.grad |
| 287 | bgrad1 = ref[0].bias.grad |
| 288 | bgrad2 = kbit[0].bias.grad |
| 289 | |
| 290 | err1 = (out1 - out2).abs().float() |
| 291 | err2 = (grad1 - grad2).abs().float() |
| 292 | relerr1 = err1 / (out1.abs().float() + 1e-9) |
| 293 | relerr2 = err2 / (grad1.abs().float() + 1e-9) |
| 294 | errs1.append(err1.mean().item()) |
| 295 | errs2.append(err2.mean().item()) |
| 296 | relerrs1.append(relerr1.mean().item()) |
| 297 | relerrs2.append(relerr2.mean().item()) |
| 298 | |
| 299 | if isinstance(module, bnb.nn.Linear8bitLt): |
| 300 | assert_all_approx_close(grad1, grad2, atol=0.008, rtol=0.05, count=1) |
| 301 | torch.testing.assert_close(bgrad1, bgrad2, atol=0.008, rtol=0.05) |
nothing calls this directly
no test coverage detected