(w, input_feat, n_bit, q_config,
n_grid=20,
max_shrink=0.5,
n_sample_token=512)
| 12 | |
| 13 | @torch.no_grad() |
| 14 | def auto_2clip_layer(w, input_feat, n_bit, q_config, |
| 15 | n_grid=20, |
| 16 | max_shrink=0.5, |
| 17 | n_sample_token=512): |
| 18 | assert w.dim() == 2 |
| 19 | org_w_shape = w.shape |
| 20 | # w [co, ci] -> [co, 1, n_group, group size] |
| 21 | # input_feat [n_token, ci] -> [1, n_token, n_group, group size] |
| 22 | |
| 23 | group_size = q_config["q_group_size"] if q_config["q_group_size"] > 0 else w.shape[1] |
| 24 | |
| 25 | input_feat = input_feat.view(-1, input_feat.shape[-1]) |
| 26 | input_feat = input_feat.reshape(1, input_feat.shape[0], -1, group_size) |
| 27 | input_feat = input_feat[:, 0::input_feat.shape[1] // n_sample_token] |
| 28 | w = w.reshape(w.shape[0], 1, -1, group_size) |
| 29 | |
| 30 | oc_batch_size = 256 if w.shape[0] % 256 == 0 else 64 # prevent OOM |
| 31 | |
| 32 | assert w.shape[0] % oc_batch_size == 0 |
| 33 | w_all = w |
| 34 | best_max_val_all = [] |
| 35 | best_min_val_all = [] |
| 36 | for i_b in range(w.shape[0] // oc_batch_size): |
| 37 | w = w_all[i_b * oc_batch_size: (i_b + 1) * oc_batch_size] |
| 38 | |
| 39 | org_max_val = w.amax(dim=-1, keepdim=True) # co, 1, n_group, 1 |
| 40 | org_min_val = w.amin(dim=-1, keepdim=True) |
| 41 | |
| 42 | best_max_val = org_max_val.clone() |
| 43 | best_min_val = org_min_val.clone() |
| 44 | |
| 45 | min_errs = torch.ones_like(org_max_val) * 1e9 |
| 46 | input_feat = input_feat.to(w.device) |
| 47 | org_out = (input_feat * w).sum(dim=-1) # co, n_token, n_group |
| 48 | |
| 49 | for i_s_p in range(int(max_shrink * n_grid)): |
| 50 | max_val = org_max_val * (1 - i_s_p / n_grid) |
| 51 | for i_s_n in range(int(max_shrink * n_grid)): |
| 52 | min_val = org_min_val * (1 - i_s_n / n_grid) |
| 53 | # min_val = - max_val |
| 54 | cur_w = torch.clamp(w, min_val, max_val) |
| 55 | if q_config["quant_type"] == "int": |
| 56 | q_w = pseudo_quantize_tensor(cur_w, n_bit=n_bit, zero_point=True, q_group_size=q_config['q_group_size']) |
| 57 | elif q_config["quant_type"] == "nf3": |
| 58 | q_w = pseudo_quantize_n2f3_tensor(cur_w, q_group_size=q_config['q_group_size']) |
| 59 | else: |
| 60 | quant_type = q_config["quant_type"] |
| 61 | raise ValueError(f"Has no support {quant_type}. Valid quant_type:[int, nf3]") |
| 62 | |
| 63 | cur_out = (input_feat * q_w).sum(dim=-1) |
| 64 | |
| 65 | err = (cur_out - org_out).pow(2).mean(dim=1).view(min_errs.shape) |
| 66 | |
| 67 | del cur_w |
| 68 | del cur_out |
| 69 | cur_best_idx = err < min_errs |
| 70 | min_errs[cur_best_idx] = err[cur_best_idx] |
| 71 | best_max_val[cur_best_idx] = max_val[cur_best_idx] |
no test coverage detected