|
6 | 6 | # Copyright (c) Meta Platforms, Inc. and affiliates. |
7 | 7 | # Licensed under the BSD 3-Clause License (see NOTICE file for details) |
8 | 8 |
|
| 9 | +import functools |
| 10 | +import os |
| 11 | + |
9 | 12 | import torch |
10 | 13 |
|
11 | 14 | from comfy_kitchen.float_utils import ( |
@@ -861,6 +864,33 @@ def dequantize_int8_simple(q: torch.Tensor, scale: torch.Tensor) -> torch.Tensor |
861 | 864 | return q.float() * scale |
862 | 865 |
|
863 | 866 |
|
| 867 | +_CDNA_ARCHS = frozenset({"gfx908", "gfx90a", "gfx940", "gfx941", "gfx942", "gfx950"}) |
| 868 | + |
| 869 | + |
| 870 | +def _use_int8_mm(device_type: str, device_index: int) -> bool: |
| 871 | + mode = os.environ.get("COMFY_KITCHEN_INT8_EAGER", "auto").strip().lower() |
| 872 | + if mode == "int_mm": |
| 873 | + return True |
| 874 | + if mode == "dequant": |
| 875 | + return False |
| 876 | + if mode == "auto": |
| 877 | + return _use_int8_mm_auto(device_type, device_index) |
| 878 | + raise ValueError("COMFY_KITCHEN_INT8_EAGER must be one of: auto, int_mm, dequant") |
| 879 | + |
| 880 | + |
| 881 | +@functools.lru_cache(maxsize=None) |
| 882 | +def _use_int8_mm_auto(device_type: str, device_index: int) -> bool: |
| 883 | + if device_type != "cuda" or not torch.cuda.is_available(): |
| 884 | + return False |
| 885 | + if getattr(torch.version, "hip", None) is None: |
| 886 | + return True |
| 887 | + try: |
| 888 | + arch = torch.cuda.get_device_properties(device_index).gcnArchName.split(":")[0] |
| 889 | + except Exception: |
| 890 | + return False |
| 891 | + return arch in _CDNA_ARCHS |
| 892 | + |
| 893 | + |
864 | 894 | def int8_linear( |
865 | 895 | x: torch.Tensor, |
866 | 896 | weight: torch.Tensor, |
@@ -908,6 +938,15 @@ def int8_linear( |
908 | 938 | h = _build_hadamard(convrot_groupsize, device=x.device, dtype=x.dtype) |
909 | 939 | x = _rotate_activation(x, h, convrot_groupsize) |
910 | 940 |
|
| 941 | + if not _use_int8_mm(x.device.type, x.device.index if x.device.index is not None else 0): |
| 942 | + ws = weight_scale.float() |
| 943 | + w = (weight.float() * (ws if ws.numel() == 1 else ws.reshape(-1, 1))).to(out_dtype) |
| 944 | + return torch.nn.functional.linear( |
| 945 | + x.to(out_dtype), |
| 946 | + w, |
| 947 | + None if bias is None else bias.to(device=x.device, dtype=out_dtype), |
| 948 | + ) |
| 949 | + |
911 | 950 | orig_shape = x.shape |
912 | 951 | x_2d = x.reshape(-1, x.shape[-1]) |
913 | 952 |
|
|
0 commit comments