diff --git a/constants/__init__.py b/constants/__init__.py index 574656d..3e7ad36 100644 --- a/constants/__init__.py +++ b/constants/__init__.py @@ -63,6 +63,11 @@ class ModelParameters: # validator scoring exponential temperature temperature = 0.08 # validator score boosting for earlier models. -timestamp_epsilon = 0.01 +timestamp_epsilon_start = 0.01 +timestamp_epsilon_min = 0.00001 +# number of blocks before decaying +timestamp_decay_start = 3600 # 3600 blocks = 12hr +# period of blocks over which to decay after the secay_start block +timestamp_decay_period = 3600 # validator eval sequence length. sequence_length = 2048 diff --git a/finetune/validation.py b/finetune/validation.py index 8c731aa..501f0a0 100644 --- a/finetune/validation.py +++ b/finetune/validation.py @@ -26,7 +26,7 @@ import bittensor as bt -def iswin(loss_i, loss_j, block_i, block_j): +def iswin(loss_i, loss_j, block_i, block_j, current_block): """ Determines the winner between two models based on the epsilon adjusted loss. @@ -39,8 +39,30 @@ def iswin(loss_i, loss_j, block_i, block_j): bool: True if loss i is better, False otherwise. """ # Adjust loss based on timestamp and pretrain epsilon - loss_i = (1 - constants.timestamp_epsilon) * loss_i if block_i < block_j else loss_i - loss_j = (1 - constants.timestamp_epsilon) * loss_j if block_j < block_i else loss_j + block_delta_i = current_block - block_i + if block_delta_i <= constants.timestamp_decay_start: + epsilon_i = constants.timestamp_epsilon + elif block_delta_i > constants.timestamp_decay_start and (block_delta_i - constants.timestamp_decay_start) <= constants.timestamp_decay_period: + epsilon_factor_i = 1 - ((block_delta_i - constants.timestamp_decay_start) / constants.timestamp_decay_period) + epsilon_i = (epsilon_factor_i * (constants.timestamp_epsilon - constants.timestamp_epsilon_min)) + constants.timestamp_epsilon_min + else: + epsilon_i = constants.timestamp_epsilon_min + + block_delta_j = current_block - block_j + if block_delta_j <= constants.timestamp_decay_start: + epsilon_j = constants.timestamp_epsilon + elif block_delta_j > constants.timestamp_decay_start and (block_delta_j - constants.timestamp_decay_start) <= constants.timestamp_decay_period: + epsilon_factor_j = 1 - ((block_delta_j - constants.timestamp_decay_start) / constants.timestamp_decay_period) + epsilon_j = (epsilon_factor_j * (constants.timestamp_epsilon - constants.timestamp_epsilon_min)) + constants.timestamp_epsilon_min + else: + epsilon_j = constants.timestamp_epsilon_min + + if block_i < block_j: + loss_i = (1 - epsilon_i) * loss_i + + if block_j < block_i: + loss_j = (1 - epsilon_j) * loss_j + return loss_i < loss_j @@ -48,6 +70,7 @@ def compute_wins( uids: typing.List[int], losses_per_uid: typing.Dict[int, typing.List[float]], uid_to_block: typing.Dict[int, int], + current_block: int ): """ Computes the wins and win rate for each model based on loss comparison. @@ -75,7 +98,7 @@ def compute_wins( for batch_idx in range(0, min(batches_i, batches_j)): loss_i = losses_per_uid[uid_i][batch_idx] loss_j = losses_per_uid[uid_j][batch_idx] - wins[uid_i] += 1 if iswin(loss_i, loss_j, block_i, block_j) else 0 + wins[uid_i] += 1 if iswin(loss_i, loss_j, block_i, block_j, current_block) else 0 total_matches += 1 # Calculate win rate for uid i win_rate[uid_i] = wins[uid_i] / total_matches if total_matches > 0 else 0 diff --git a/neurons/validator.py b/neurons/validator.py index 567f3c5..dd1cb67 100644 --- a/neurons/validator.py +++ b/neurons/validator.py @@ -445,7 +445,7 @@ def sync_metagraph(endpoint): # Update self.metagraph self.metagraph = bt.subtensor(endpoint).metagraph(self.config.netuid) self.metagraph.save() - + process = multiprocessing.Process( target=sync_metagraph, args=(self.subtensor.chain_endpoint,) ) @@ -486,7 +486,7 @@ async def run_step(self): # Update self.metagraph await self.try_sync_metagraph(ttl=60) - + # Add uids with newly updated models to the upcoming batch of evaluations. with self.pending_uids_to_eval_lock: self.uids_to_eval.update(self.pending_uids_to_eval) @@ -625,7 +625,7 @@ async def run_step(self): # Compute wins and win rates per uid. wins, win_rate = ft.validation.compute_wins( - uids, losses_per_uid, uid_to_block + uids, losses_per_uid, uid_to_block, self.metagraph.block ) # Compute softmaxed weights based on win rate.