From 6cafb4b6d960459b2c3e081d06e2d8e11d26f4e3 Mon Sep 17 00:00:00 2001 From: opentaco Date: Wed, 29 Mar 2023 13:41:54 +0200 Subject: [PATCH 1/3] Change u16 weight normalization to max-upscaling Use full u16 bitwidth so that max_weight=U16_MAX, then rely on subtensor epoch to properly normalize weights in I32F32. This means that weights submission extrinsic to subtensor does not have to be pre-normalized. --- bittensor/utils/weight_utils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bittensor/utils/weight_utils.py b/bittensor/utils/weight_utils.py index c89d6a9c34..b96b5a21a7 100644 --- a/bittensor/utils/weight_utils.py +++ b/bittensor/utils/weight_utils.py @@ -80,7 +80,8 @@ def convert_weight_uids_and_vals_to_tensor( n: int, uids: List[int], weights: Li """ row_weights = torch.zeros( [ n ], dtype=torch.float32 ) for uid_j, wij in list(zip( uids, weights )): - row_weights[ uid_j ] = float( wij ) / float(U16_MAX) + row_weights[ uid_j ] = float( wij ) # assumes max-upscaled values (w_max = U16_MAX). + row_weights /= row_weights.sum() # normalize return row_weights def convert_bond_uids_and_vals_to_tensor( n: int, uids: List[int], bonds: List[int] ) -> 'torch.LongTensor': @@ -119,6 +120,8 @@ def convert_weights_and_uids_for_emit( uids: torch.LongTensor, weights: torch.Fl uids = uids.tolist() if min(weights) < 0: raise ValueError('Passed weight is negative cannot exist on chain {}'.format(weights)) + if max(weights) == 0: + raise ValueError('Passed weight all zero cannot exist on chain {}'.format(weights)) if min(uids) < 0: raise ValueError('Passed uid is negative cannot exist on chain {}'.format(uids)) if len(uids) != len(weights): @@ -126,7 +129,8 @@ def convert_weights_and_uids_for_emit( uids: torch.LongTensor, weights: torch.Fl if sum(weights) == 0: return [],[] # Nothing to set on chain. else: - weights = [ float(value) / sum(weights) for value in weights] # Initial normalization. + max_weight = float(max(weights)) + weights = [float(value) / max_weight for value in weights] # max-upscale values (max_weight = 1). weight_vals = [] weight_uids = [] From fc0dabba38822c673668eff1e50198151b0e6b6a Mon Sep 17 00:00:00 2001 From: opentaco Date: Wed, 29 Mar 2023 17:32:41 +0200 Subject: [PATCH 2/3] Skip zero sum in weight conversion --- bittensor/utils/weight_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bittensor/utils/weight_utils.py b/bittensor/utils/weight_utils.py index b96b5a21a7..58179d7b8e 100644 --- a/bittensor/utils/weight_utils.py +++ b/bittensor/utils/weight_utils.py @@ -81,7 +81,9 @@ def convert_weight_uids_and_vals_to_tensor( n: int, uids: List[int], weights: Li row_weights = torch.zeros( [ n ], dtype=torch.float32 ) for uid_j, wij in list(zip( uids, weights )): row_weights[ uid_j ] = float( wij ) # assumes max-upscaled values (w_max = U16_MAX). - row_weights /= row_weights.sum() # normalize + row_sum = row_weights.sum() + if row_sum > 0: + row_weights /= row_sum # normalize return row_weights def convert_bond_uids_and_vals_to_tensor( n: int, uids: List[int], bonds: List[int] ) -> 'torch.LongTensor': @@ -120,8 +122,6 @@ def convert_weights_and_uids_for_emit( uids: torch.LongTensor, weights: torch.Fl uids = uids.tolist() if min(weights) < 0: raise ValueError('Passed weight is negative cannot exist on chain {}'.format(weights)) - if max(weights) == 0: - raise ValueError('Passed weight all zero cannot exist on chain {}'.format(weights)) if min(uids) < 0: raise ValueError('Passed uid is negative cannot exist on chain {}'.format(uids)) if len(uids) != len(weights): From 820c6f7a2410591a0de8d9aaa2c9c3aba17b509d Mon Sep 17 00:00:00 2001 From: opentaco Date: Wed, 5 Apr 2023 11:00:17 +0200 Subject: [PATCH 3/3] Round u16 weights --- bittensor/utils/weight_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/utils/weight_utils.py b/bittensor/utils/weight_utils.py index 58179d7b8e..5f5c8b9dc8 100644 --- a/bittensor/utils/weight_utils.py +++ b/bittensor/utils/weight_utils.py @@ -135,7 +135,7 @@ def convert_weights_and_uids_for_emit( uids: torch.LongTensor, weights: torch.Fl weight_vals = [] weight_uids = [] for i, (weight_i, uid_i) in enumerate(list(zip(weights, uids))): - uint16_val = int(float(weight_i) * int(U16_MAX)) # convert to int representation. + uint16_val = round(float(weight_i) * int(U16_MAX)) # convert to int representation. # Filter zeros if uint16_val != 0: # Filter zeros