From 51e74c20eb9747f30d96ab62386857c05701ba9e Mon Sep 17 00:00:00 2001 From: Eugene Date: Mon, 16 Jan 2023 16:10:05 -0800 Subject: [PATCH 1/8] additional parameters --- .../_neuron/text/core_validator/__init__.py | 39 +++++++++++++------ bittensor/_subtensor/subtensor_impl.py | 26 +++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index 41278e6207..1161464a0f 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -234,7 +234,7 @@ def add_args( cls, parser ): parser.add_argument('--neuron.blocks_per_epoch', type=int, help='Blocks per epoch, -1 value means we use the chain value.', default = -1 ) parser.add_argument('--neuron.epochs_until_reset', type=int, help='Number of epochs before weights are reset.', default = -1 ) parser.add_argument('--neuron.validation_len', type=int, help='Number of tokens to holdout for phrase validation beyond sequence context.', default=8) - parser.add_argument('--neuron.prune_len', type=int, help='Number of tokens to prune from each validation input sequence.', default=1) + parser.add_argument('--neuron.prune_len', type=int, help='Number of tokens to prune from each validation input sequence. (default value: -1, pulling from subtensor directly)', default=-1) parser.add_argument('--neuron.device', type=str, help='miner default training device cpu/cuda', default=("cuda" if torch.cuda.is_available() else "cpu")) parser.add_argument('--neuron.clip_gradients', type=float, help='Implement gradient clipping to avoid exploding loss on smaller architectures.', default=1.0 ) parser.add_argument('--neuron.track_hotkey_changes', action='store_true', help='If True, track hotkey changes.', default=False) @@ -400,13 +400,16 @@ def run_epoch( self ): batch_size = self.subtensor.validator_batch_size sequence_length = self.subtensor.validator_sequence_length validation_len = self.config.neuron.validation_len # Number of tokens to holdout for phrase validation beyond sequence context - prune_len = self.config.neuron.prune_len # Number of tokens to holdout for phrase validation beyond sequence context + # Number of tokens to prune for phrase validation beyond sequence context + prune_len = self.subtensor.prune_len if self.config.neuron.prune_len == -1 else self.config.neuron.prune_len + nexc_intensity = self.subtensor.nexc_intensity min_allowed_weights = self.subtensor.min_allowed_weights max_weight_limit = self.subtensor.max_weight_limit blocks_per_epoch = self.subtensor.validator_epoch_length if self.config.neuron.blocks_per_epoch == -1 else self.config.neuron.blocks_per_epoch epochs_until_reset = self.subtensor.validator_epochs_per_reset if self.config.neuron.epochs_until_reset == -1 else self.config.neuron.epochs_until_reset self.config.nucleus.scaling_law_power = self.subtensor.scaling_law_power self.config.nucleus.synergy_scaling_law_power = self.subtensor.synergy_scaling_law_power + self.config.nucleus.nexc_intensity = self.subtensor.nexc_intensity # === Logs Prometheus === self.prometheus_gauges.labels("current_block").set( current_block ) @@ -825,6 +828,7 @@ def __init__( self, config, device, subtensor ): self.config.nucleus.scaling_law_power = subtensor.scaling_law_power if self.config.nucleus.scaling_law_power == -1 else self.config.nucleus.scaling_law_power self.config.nucleus.synergy_scaling_law_power = subtensor.synergy_scaling_law_power if self.config.nucleus.synergy_scaling_law_power == -1 else self.config.nucleus.synergy_scaling_law_power + self.config.nucleus.nexc_intensity = subtensor.nexc_intensity if self.config.nucleus.nexc_intensity == -1 else self.config.nucleus.nexc_intensity self.device = device self.max_n = subtensor.max_n @@ -872,6 +876,7 @@ def add_args( cls, parser ): parser.add_argument('--nucleus.no_dendrite_backward', action='store_true', help='Pass backward request to the server side or not', default=False ) parser.add_argument('--nucleus.scaling_law_power', type=float, help='Power for modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) parser.add_argument('--nucleus.synergy_scaling_law_power', type=float, help='Power for synergy modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) + parser.add_argument('--nucleus.nexc_intensity', type=float, help=' the intensity value for nExc anomaly detection (default value: -1, pulling from subtensor directly)', default=-1) @classmethod def config ( cls ): @@ -1025,10 +1030,20 @@ def forward( # === Prepare validation parameter set === console_width = self.config.get('width', None) # console width for rich table displays of synapse measures - validation_params = (random_uids, query_responses, return_ops, times, routing_score, - inputs, val_len, self.loss_fct, - self.config.nucleus.scaling_law_power, self.config.nucleus.synergy_scaling_law_power, - console_width, self.config.logging.debug or self.config.logging.trace) + validation_params = { + 'uids': random_uids, + 'query_responses': query_responses, + 'return_ops': return_ops, + 'times': times, + 'routing_score': routing_score, + 'inputs': inputs, + 'validation_len': val_len, + 'loss_fct': self.loss_fct, + 'scaling_law_power': self.config.nucleus.scaling_law_power, + 'synergy_scaling_law_power': self.config.nucleus.synergy_scaling_law_power, + 'nexc_intensity': self.config.nucleus.nexc_intensity, + 'logging': self.config.logging.debug or self.config.logging.trace + } loss = torch.tensor(0.).to(self.device) # to accumulate neuron_loss and routing_loss over synapses neuron_stats = {} # to gather neuron synapse validation measures and statistics @@ -1185,8 +1200,8 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT times: List[torch.FloatTensor], routing_score: torch.FloatTensor, inputs: torch.FloatTensor, validation_len: int, loss_fct: Callable, scaling_law_power: float, synergy_scaling_law_power: float, - console_width: int, logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0 - ) -> Tuple[torch.FloatTensor, Dict]: + logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0, + nexc_intensity: float = 3.0) -> Tuple[torch.FloatTensor, Dict]: r""" Calculate Shapley values and neuron response validation measure statistics, given TextCausalLMNext synapse responses. Args: @@ -1219,6 +1234,8 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT TextCausalLMNext Synapse object. index_s (:obj:`int`, `optional`): Index of synapse to extract responses. + nexc_intensity (:obj:`float`, `optional`) + Intensity for the nexc anomaly detection Returns: loss (:obj:`torch.FloatTensor`): @@ -1255,7 +1272,7 @@ def _synergy(first, second, target, ext): divergence_start_time = time.time() with torch.no_grad(): - logits_divergence(stats, uids, query_responses, return_ops, times, index_s, ext='_nxt') + logits_divergence(stats, uids, query_responses, return_ops, times, index_s, ext='_nxt', nexc_intensity=nexc_intensity) logger.info(f'{str(synapse)} \t| Logits divergences [{time.time() - divergence_start_time:.3g}s]') synergy_start_time = time.time() @@ -1375,7 +1392,7 @@ def shapley_base(uids: torch.Tensor, query_responses: List[List[torch.FloatTenso def logits_divergence(stats: Dict, uids: torch.Tensor, query_responses: List[List[torch.FloatTensor]], return_ops: List[torch.LongTensor], times: List[torch.FloatTensor], - index_s: int = 0, ext: str = None): + index_s: int = 0, ext: str = None, nexc_intensity:float = 3): r""" Calculate each logits divergence per neuron per task from the average logits over all neurons per task, given responses from a synapse. @@ -1457,7 +1474,7 @@ def logits_divergence(stats: Dict, uids: torch.Tensor, query_responses: List[Lis try: excess = torch.clamp(_stats['logits_divergences' + ext] - (avg + std), 0) # divergence > avg + std excess /= std + 1e-9 # stddev multiples above 1 stddev - excess = torch.pow(excess, 3) # reduce < 2std, increase > 2std + excess = torch.pow(excess, nexc_intensity) # reduce < 2std, increase > 2std excess = torch.clamp(excess, 0, 10) # maximum excess ratio of 10 _stats['logits_excess' + ext] = excess.mean() # in [0, 10] diff --git a/bittensor/_subtensor/subtensor_impl.py b/bittensor/_subtensor/subtensor_impl.py index 5f2bd19ca1..67b5dedcbe 100644 --- a/bittensor/_subtensor/subtensor_impl.py +++ b/bittensor/_subtensor/subtensor_impl.py @@ -424,6 +424,32 @@ def make_substrate_call_with_retry(): ).value return make_substrate_call_with_retry() + @property + def prune_len (self) -> int: + r""" Returns PruneLen + Returns: + prune_len (int): + the number of pruned tokens from each requests + """ + @retry(delay=2, tries=3, backoff=2, max_delay=4) + def make_substrate_call_with_retry(): + with self.substrate as substrate: + return substrate.query( module='SubtensorModule', storage_function = 'PruneLen' ).value + return make_substrate_call_with_retry() + + @property + def nexc_intensity (self) -> int: + r""" Returns nExcIntensity + Returns: + nexc_intensity (int): + the intensity value for nExc, a measure for anomaly detection + """ + @retry(delay=2, tries=3, backoff=2, max_delay=4) + def make_substrate_call_with_retry(): + with self.substrate as substrate: + U32_MAX = 4294967295 + return substrate.query( module='SubtensorModule', storage_function = 'nExcIntensity' ).value/U32_MAX + return make_substrate_call_with_retry() def serve_axon ( self, From f653afd10993d355d3376779d6084e42167a2cda Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 17 Jan 2023 09:33:57 -0800 Subject: [PATCH 2/8] fixed naming to logit divergence --- .../_neuron/text/core_validator/__init__.py | 20 ++++++++----------- bittensor/_subtensor/subtensor_impl.py | 14 ++++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index 1161464a0f..cb1fa0e004 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -402,14 +402,13 @@ def run_epoch( self ): validation_len = self.config.neuron.validation_len # Number of tokens to holdout for phrase validation beyond sequence context # Number of tokens to prune for phrase validation beyond sequence context prune_len = self.subtensor.prune_len if self.config.neuron.prune_len == -1 else self.config.neuron.prune_len - nexc_intensity = self.subtensor.nexc_intensity min_allowed_weights = self.subtensor.min_allowed_weights max_weight_limit = self.subtensor.max_weight_limit blocks_per_epoch = self.subtensor.validator_epoch_length if self.config.neuron.blocks_per_epoch == -1 else self.config.neuron.blocks_per_epoch epochs_until_reset = self.subtensor.validator_epochs_per_reset if self.config.neuron.epochs_until_reset == -1 else self.config.neuron.epochs_until_reset self.config.nucleus.scaling_law_power = self.subtensor.scaling_law_power self.config.nucleus.synergy_scaling_law_power = self.subtensor.synergy_scaling_law_power - self.config.nucleus.nexc_intensity = self.subtensor.nexc_intensity + self.config.nucleus.logit_divergence = self.subtensor.logit_divergence # === Logs Prometheus === self.prometheus_gauges.labels("current_block").set( current_block ) @@ -691,7 +690,7 @@ def neuron_stats_update(self, neuron_stats: Dict[int, Dict[str, Any]]): if 'logits_excess_nxt' in stats: # penalize by logits divergence excess - extra_stats['shapley_values_nxt'] /= 1 + stats['logits_excess_nxt'] + extra_stats['shapley_values_nxt'] /= 1 + self.config.neuron.logits_divergence_penalty * stats['logits_excess_nxt'] # === EMA zeroing update === # Push zero into EMA for synapse_keys to exponentially decay weighting keys if neuron non-responsive @@ -828,7 +827,7 @@ def __init__( self, config, device, subtensor ): self.config.nucleus.scaling_law_power = subtensor.scaling_law_power if self.config.nucleus.scaling_law_power == -1 else self.config.nucleus.scaling_law_power self.config.nucleus.synergy_scaling_law_power = subtensor.synergy_scaling_law_power if self.config.nucleus.synergy_scaling_law_power == -1 else self.config.nucleus.synergy_scaling_law_power - self.config.nucleus.nexc_intensity = subtensor.nexc_intensity if self.config.nucleus.nexc_intensity == -1 else self.config.nucleus.nexc_intensity + self.config.nucleus.logit_divergence = subtensor.logit_divergence if self.config.nucleus.logit_divergence == -1 else self.config.nucleus.logit_divergence self.device = device self.max_n = subtensor.max_n @@ -876,7 +875,7 @@ def add_args( cls, parser ): parser.add_argument('--nucleus.no_dendrite_backward', action='store_true', help='Pass backward request to the server side or not', default=False ) parser.add_argument('--nucleus.scaling_law_power', type=float, help='Power for modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) parser.add_argument('--nucleus.synergy_scaling_law_power', type=float, help='Power for synergy modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) - parser.add_argument('--nucleus.nexc_intensity', type=float, help=' the intensity value for nExc anomaly detection (default value: -1, pulling from subtensor directly)', default=-1) + parser.add_argument('--nucleus.logit_divergence', type=float, help=' the divergence value for logit anomaly detection (default value: -1, pulling from subtensor directly)', default=-1) @classmethod def config ( cls ): @@ -1041,7 +1040,6 @@ def forward( 'loss_fct': self.loss_fct, 'scaling_law_power': self.config.nucleus.scaling_law_power, 'synergy_scaling_law_power': self.config.nucleus.synergy_scaling_law_power, - 'nexc_intensity': self.config.nucleus.nexc_intensity, 'logging': self.config.logging.debug or self.config.logging.trace } @@ -1201,7 +1199,7 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT inputs: torch.FloatTensor, validation_len: int, loss_fct: Callable, scaling_law_power: float, synergy_scaling_law_power: float, logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0, - nexc_intensity: float = 3.0) -> Tuple[torch.FloatTensor, Dict]: + ) -> Tuple[torch.FloatTensor, Dict]: r""" Calculate Shapley values and neuron response validation measure statistics, given TextCausalLMNext synapse responses. Args: @@ -1234,8 +1232,6 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT TextCausalLMNext Synapse object. index_s (:obj:`int`, `optional`): Index of synapse to extract responses. - nexc_intensity (:obj:`float`, `optional`) - Intensity for the nexc anomaly detection Returns: loss (:obj:`torch.FloatTensor`): @@ -1272,7 +1268,7 @@ def _synergy(first, second, target, ext): divergence_start_time = time.time() with torch.no_grad(): - logits_divergence(stats, uids, query_responses, return_ops, times, index_s, ext='_nxt', nexc_intensity=nexc_intensity) + logits_divergence(stats, uids, query_responses, return_ops, times, index_s, ext='_nxt') logger.info(f'{str(synapse)} \t| Logits divergences [{time.time() - divergence_start_time:.3g}s]') synergy_start_time = time.time() @@ -1392,7 +1388,7 @@ def shapley_base(uids: torch.Tensor, query_responses: List[List[torch.FloatTenso def logits_divergence(stats: Dict, uids: torch.Tensor, query_responses: List[List[torch.FloatTensor]], return_ops: List[torch.LongTensor], times: List[torch.FloatTensor], - index_s: int = 0, ext: str = None, nexc_intensity:float = 3): + index_s: int = 0, ext: str = None): r""" Calculate each logits divergence per neuron per task from the average logits over all neurons per task, given responses from a synapse. @@ -1474,7 +1470,7 @@ def logits_divergence(stats: Dict, uids: torch.Tensor, query_responses: List[Lis try: excess = torch.clamp(_stats['logits_divergences' + ext] - (avg + std), 0) # divergence > avg + std excess /= std + 1e-9 # stddev multiples above 1 stddev - excess = torch.pow(excess, nexc_intensity) # reduce < 2std, increase > 2std + excess = torch.pow(excess) # reduce < 2std, increase > 2std excess = torch.clamp(excess, 0, 10) # maximum excess ratio of 10 _stats['logits_excess' + ext] = excess.mean() # in [0, 10] diff --git a/bittensor/_subtensor/subtensor_impl.py b/bittensor/_subtensor/subtensor_impl.py index 67b5dedcbe..4c385f2c64 100644 --- a/bittensor/_subtensor/subtensor_impl.py +++ b/bittensor/_subtensor/subtensor_impl.py @@ -434,21 +434,21 @@ def prune_len (self) -> int: @retry(delay=2, tries=3, backoff=2, max_delay=4) def make_substrate_call_with_retry(): with self.substrate as substrate: - return substrate.query( module='SubtensorModule', storage_function = 'PruneLen' ).value + return substrate.query( module='SubtensorModule', storage_function = 'ValidatorPruneLen' ).value return make_substrate_call_with_retry() @property - def nexc_intensity (self) -> int: - r""" Returns nExcIntensity + def logit_divergence (self) -> int: + r""" Returns Logit_Divergence Returns: - nexc_intensity (int): - the intensity value for nExc, a measure for anomaly detection + logit_divergence (int): + the divergence value for logit distances, a measure for anomaly detection """ @retry(delay=2, tries=3, backoff=2, max_delay=4) def make_substrate_call_with_retry(): with self.substrate as substrate: - U32_MAX = 4294967295 - return substrate.query( module='SubtensorModule', storage_function = 'nExcIntensity' ).value/U32_MAX + U64MAX = 18446744073709551615 + return substrate.query( module='SubtensorModule', storage_function = 'ValidatorLogitsDivergence' ).value/U64MAX return make_substrate_call_with_retry() def serve_axon ( From db2d275128c1ec0856c0c6f3041f096ce01f3374 Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 17 Jan 2023 09:55:56 -0800 Subject: [PATCH 3/8] versioning and fixes --- VERSION | 2 +- bittensor/__init__.py | 2 +- .../_neuron/text/core_validator/__init__.py | 21 ++++++------------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index 9575d51bad..77a069e39b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.6.1 +3.6.2 \ No newline at end of file diff --git a/bittensor/__init__.py b/bittensor/__init__.py index 150095f87b..9b2472f433 100644 --- a/bittensor/__init__.py +++ b/bittensor/__init__.py @@ -23,7 +23,7 @@ nest_asyncio.apply() # Bittensor code and protocol version. -__version__ = '3.6.1' +__version__ = '3.6.2' version_split = __version__.split(".") __version_as_int__ = (100 * int(version_split[0])) + (10 * int(version_split[1])) + (1 * int(version_split[2])) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index cb1fa0e004..51eaa4e070 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -1029,19 +1029,10 @@ def forward( # === Prepare validation parameter set === console_width = self.config.get('width', None) # console width for rich table displays of synapse measures - validation_params = { - 'uids': random_uids, - 'query_responses': query_responses, - 'return_ops': return_ops, - 'times': times, - 'routing_score': routing_score, - 'inputs': inputs, - 'validation_len': val_len, - 'loss_fct': self.loss_fct, - 'scaling_law_power': self.config.nucleus.scaling_law_power, - 'synergy_scaling_law_power': self.config.nucleus.synergy_scaling_law_power, - 'logging': self.config.logging.debug or self.config.logging.trace - } + validation_params = (random_uids, query_responses, return_ops, times, routing_score, + inputs, val_len, self.loss_fct, + self.config.nucleus.scaling_law_power, self.config.nucleus.synergy_scaling_law_power, + console_width, self.config.logging.debug or self.config.logging.trace) loss = torch.tensor(0.).to(self.device) # to accumulate neuron_loss and routing_loss over synapses neuron_stats = {} # to gather neuron synapse validation measures and statistics @@ -1198,7 +1189,7 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT times: List[torch.FloatTensor], routing_score: torch.FloatTensor, inputs: torch.FloatTensor, validation_len: int, loss_fct: Callable, scaling_law_power: float, synergy_scaling_law_power: float, - logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0, + console_width: int, logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0, ) -> Tuple[torch.FloatTensor, Dict]: r""" Calculate Shapley values and neuron response validation measure statistics, given TextCausalLMNext synapse responses. @@ -1470,7 +1461,7 @@ def logits_divergence(stats: Dict, uids: torch.Tensor, query_responses: List[Lis try: excess = torch.clamp(_stats['logits_divergences' + ext] - (avg + std), 0) # divergence > avg + std excess /= std + 1e-9 # stddev multiples above 1 stddev - excess = torch.pow(excess) # reduce < 2std, increase > 2std + excess = torch.pow(excess, 3) # reduce < 2std, increase > 2std excess = torch.clamp(excess, 0, 10) # maximum excess ratio of 10 _stats['logits_excess' + ext] = excess.mean() # in [0, 10] From e54e51f8609c93031ccbbd7e8c9c4744667f4f31 Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 17 Jan 2023 11:21:29 -0800 Subject: [PATCH 4/8] typo fixes --- bittensor/_neuron/text/core_validator/__init__.py | 8 ++++---- bittensor/_subtensor/subtensor_impl.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index 51eaa4e070..c972bbe909 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -408,7 +408,7 @@ def run_epoch( self ): epochs_until_reset = self.subtensor.validator_epochs_per_reset if self.config.neuron.epochs_until_reset == -1 else self.config.neuron.epochs_until_reset self.config.nucleus.scaling_law_power = self.subtensor.scaling_law_power self.config.nucleus.synergy_scaling_law_power = self.subtensor.synergy_scaling_law_power - self.config.nucleus.logit_divergence = self.subtensor.logit_divergence + self.config.nucleus.logits_divergence = self.subtensor.logits_divergence # === Logs Prometheus === self.prometheus_gauges.labels("current_block").set( current_block ) @@ -690,7 +690,7 @@ def neuron_stats_update(self, neuron_stats: Dict[int, Dict[str, Any]]): if 'logits_excess_nxt' in stats: # penalize by logits divergence excess - extra_stats['shapley_values_nxt'] /= 1 + self.config.neuron.logits_divergence_penalty * stats['logits_excess_nxt'] + extra_stats['shapley_values_nxt'] /= 1 + self.config.neuron.logits_divergence * stats['logits_excess_nxt'] # === EMA zeroing update === # Push zero into EMA for synapse_keys to exponentially decay weighting keys if neuron non-responsive @@ -827,7 +827,7 @@ def __init__( self, config, device, subtensor ): self.config.nucleus.scaling_law_power = subtensor.scaling_law_power if self.config.nucleus.scaling_law_power == -1 else self.config.nucleus.scaling_law_power self.config.nucleus.synergy_scaling_law_power = subtensor.synergy_scaling_law_power if self.config.nucleus.synergy_scaling_law_power == -1 else self.config.nucleus.synergy_scaling_law_power - self.config.nucleus.logit_divergence = subtensor.logit_divergence if self.config.nucleus.logit_divergence == -1 else self.config.nucleus.logit_divergence + self.config.nucleus.logits_divergence = subtensor.logits_divergence if self.config.nucleus.logits_divergence == -1 else self.config.nucleus.logits_divergence self.device = device self.max_n = subtensor.max_n @@ -875,7 +875,7 @@ def add_args( cls, parser ): parser.add_argument('--nucleus.no_dendrite_backward', action='store_true', help='Pass backward request to the server side or not', default=False ) parser.add_argument('--nucleus.scaling_law_power', type=float, help='Power for modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) parser.add_argument('--nucleus.synergy_scaling_law_power', type=float, help='Power for synergy modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. (default value: -1, pulling from subtensor directly)', default=-1) - parser.add_argument('--nucleus.logit_divergence', type=float, help=' the divergence value for logit anomaly detection (default value: -1, pulling from subtensor directly)', default=-1) + parser.add_argument('--nucleus.logits_divergence', type=float, help=' the divergence value for logit anomaly detection (default value: -1, pulling from subtensor directly)', default=-1) @classmethod def config ( cls ): diff --git a/bittensor/_subtensor/subtensor_impl.py b/bittensor/_subtensor/subtensor_impl.py index 4c385f2c64..38d62d38cd 100644 --- a/bittensor/_subtensor/subtensor_impl.py +++ b/bittensor/_subtensor/subtensor_impl.py @@ -438,10 +438,10 @@ def make_substrate_call_with_retry(): return make_substrate_call_with_retry() @property - def logit_divergence (self) -> int: - r""" Returns Logit_Divergence + def logits_divergence (self) -> int: + r""" Returns logits_divergence Returns: - logit_divergence (int): + logits_divergence (int): the divergence value for logit distances, a measure for anomaly detection """ @retry(delay=2, tries=3, backoff=2, max_delay=4) From 11355f734b158491bc86071260b14b44d19de3da Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 17 Jan 2023 13:23:43 -0800 Subject: [PATCH 5/8] bug fixes --- bittensor/_neuron/text/core_validator/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index c972bbe909..1a74cb9dfc 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -169,7 +169,7 @@ def __init__( self.device = torch.device ( device = self.config.neuron.device ) self.nucleus = nucleus ( config = self.config, device = self.device, subtensor = self.subtensor ).to( self.device ) self.dataset = (bittensor.dataset(config=self.config, batch_size=self.subtensor.validator_batch_size, - block_size=self.subtensor.validator_sequence_length + self.config.neuron.validation_len) + block_size=self.subtensor.validator_sequence_length + self.config.neuron.validation_len + self.subtensor.prune_len) if dataset is None else dataset) self.optimizer = torch.optim.SGD( self.nucleus.parameters(), lr=self.config.neuron.learning_rate, momentum=self.config.neuron.momentum @@ -690,7 +690,7 @@ def neuron_stats_update(self, neuron_stats: Dict[int, Dict[str, Any]]): if 'logits_excess_nxt' in stats: # penalize by logits divergence excess - extra_stats['shapley_values_nxt'] /= 1 + self.config.neuron.logits_divergence * stats['logits_excess_nxt'] + extra_stats['shapley_values_nxt'] /= 1 + self.config.nucleus.logits_divergence * stats['logits_excess_nxt'] # === EMA zeroing update === # Push zero into EMA for synapse_keys to exponentially decay weighting keys if neuron non-responsive From 42b6ebeb8c71a50f9f0e411ea857982b8d3d14fd Mon Sep 17 00:00:00 2001 From: Eugene-hu <85906264+Eugene-hu@users.noreply.github.com> Date: Tue, 17 Jan 2023 13:31:10 -0800 Subject: [PATCH 6/8] Tests cli fixes (#1058) * fix btcli list with wallet.path (#1036) fix path join * remove mock subtensor and replace with mock calls * additional fixes * mock wallet Co-authored-by: Cameron Fairchild --- bittensor/_cli/cli_impl.py | 2 +- tests/integration_tests/test_cli.py | 206 ++++++---------------------- 2 files changed, 40 insertions(+), 168 deletions(-) diff --git a/bittensor/_cli/cli_impl.py b/bittensor/_cli/cli_impl.py index 846d5111ee..889057227a 100644 --- a/bittensor/_cli/cli_impl.py +++ b/bittensor/_cli/cli_impl.py @@ -477,7 +477,7 @@ def list(self): coldkeypub_str = '?' wallet_tree = root.add("\n[bold white]{} ({})".format(w_name, coldkeypub_str)) - hotkeys_path = self.config.wallet.path + w_name + '/hotkeys' + hotkeys_path = os.path.join(self.config.wallet.path, w_name, 'hotkeys') try: hotkeys = next(os.walk(os.path.expanduser(hotkeys_path))) if len( hotkeys ) > 1: diff --git a/tests/integration_tests/test_cli.py b/tests/integration_tests/test_cli.py index 40f613f5bb..4164103c4f 100644 --- a/tests/integration_tests/test_cli.py +++ b/tests/integration_tests/test_cli.py @@ -24,6 +24,7 @@ import pytest import bittensor +import substrateinterface from bittensor._subtensor.subtensor_mock import mock_subtensor from bittensor.utils.balance import Balance from substrateinterface.base import Keypair @@ -33,7 +34,13 @@ class TestCli(unittest.TestCase): def setUp(self): - mock_subtensor.kill_global_mock_process() + class success(): + def __init__(self): + self.is_success = True + self.value = 1 + def process_events(self): + return True + self.config = TestCli.construct_config() # Mocked objects self.mock_neuron = TestCli._neuron_dict_to_namespace( @@ -61,6 +68,13 @@ def setUp(self): "is_null":False }) ) + bittensor.Subtensor.register = MagicMock(return_value = True) + bittensor.Subtensor.neuron_for_pubkey = MagicMock(return_value=self.mock_neuron) + bittensor.Subtensor.neuron_for_uid = MagicMock(return_value=self.mock_neuron) + substrateinterface.SubstrateInterface.submit_extrinsic = MagicMock(return_value = success()) + substrateinterface.SubstrateInterface.query = MagicMock(return_value=success()) + substrateinterface.SubstrateInterface.get_block_hash = MagicMock(return_value='0x') + bittensor.Subtensor.get_balance = MagicMock(return_value = Balance.from_tao(0)) @staticmethod def construct_config(): @@ -93,7 +107,7 @@ def _neuron_dict_to_namespace(neuron_dict) -> SimpleNamespace: @staticmethod def generate_wallet(coldkey : 'Keypair' = None, hotkey: 'Keypair' = None): - wallet = bittensor.wallet(_mock=True) + wallet = bittensor.wallet(_mock=True).create() if not coldkey: coldkey = Keypair.create_from_mnemonic(Keypair.generate_mnemonic()) @@ -142,8 +156,6 @@ def test_overview( self ): config.wallet.name = 'mock_wallet' config.command = "overview" config.no_cache = True # Don't use neuron cache - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -171,8 +183,6 @@ def test_overview_no_wallet( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -181,13 +191,9 @@ def test_overview_no_wallet( self ): cli.run() def test_overview_with_cache( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - config = self.config config.command = "overview" config.no_cache = False # Use neuron cache - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -196,13 +202,9 @@ def test_overview_with_cache( self ): cli.run() def test_overview_with_cache_cache_fails( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - config = self.config config.command = "overview" config.no_cache = False # Use neuron cache - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -215,14 +217,10 @@ def test_overview_with_cache_cache_fails( self ): cli = bittensor.cli(config) cli.run() - def test_overview_without_no_cache_confg( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_without_no_cache_confg( self ): config = self.config config.command = "overview" # Don't specify no_cache in config - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -230,13 +228,9 @@ def test_overview_without_no_cache_confg( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_hotkeys_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_hotkeys_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.wallet.hotkeys = ['some_hotkey'] config.all = False @@ -245,13 +239,9 @@ def test_overview_with_hotkeys_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_without_hotkeys_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_without_hotkeys_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -259,13 +249,9 @@ def test_overview_without_hotkeys_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_sort_by_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_sort_by_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.wallet.sort_by = "rank" config.all = False @@ -274,13 +260,9 @@ def test_overview_with_sort_by_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_sort_by_bad_column_name( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_sort_by_bad_column_name( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.wallet.sort_by = "totallynotmatchingcolumnname" config.all = False @@ -289,13 +271,9 @@ def test_overview_with_sort_by_bad_column_name( self ): cli = bittensor.cli(config) cli.run() - def test_overview_without_sort_by_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_without_sort_by_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -303,14 +281,10 @@ def test_overview_without_sort_by_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_sort_order_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_sort_order_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True config.wallet.sort_order = "desc" # Set descending sort order - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -318,14 +292,10 @@ def test_overview_with_sort_order_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_sort_order_config_bad_sort_type( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_sort_order_config_bad_sort_type( self ): config = self.config config.command = "overview" - config.subtensor._mock = True config.wallet.sort_order = "nowaythisshouldmatchanyorderingchoice" - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -333,14 +303,10 @@ def test_overview_with_sort_order_config_bad_sort_type( self ): cli = bittensor.cli(config) cli.run() - def test_overview_without_sort_order_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_without_sort_order_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True # Don't specify sort_order in config - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -348,14 +314,10 @@ def test_overview_without_sort_order_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_with_width_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_with_width_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True config.width = 100 - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -363,14 +325,10 @@ def test_overview_with_width_config( self ): cli = bittensor.cli(config) cli.run() - def test_overview_without_width_config( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_overview_without_width_config( self ): config = self.config config.command = "overview" - config.subtensor._mock = True # Don't specify width in config - config.subtensor.network = "mock" config.no_prompt = True config.all = False config.no_version_checking = False @@ -379,12 +337,8 @@ def test_overview_without_width_config( self ): cli.run() def test_overview_all( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - config = self.config config.command = "overview" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.no_version_checking = False @@ -392,13 +346,9 @@ def test_overview_all( self ): cli = bittensor.cli(config) cli.run() - def test_unstake_with_specific_hotkeys( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_unstake_with_specific_hotkeys( self ): config = self.config config.command = "unstake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -474,12 +424,8 @@ def test_unstake_with_specific_hotkeys( self ): ) def test_unstake_with_all_hotkeys( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - config = self.config config.command = "unstake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -528,12 +474,8 @@ def test_unstake_with_all_hotkeys( self ): ) def test_unstake_with_exclude_hotkeys_from_all( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - config = self.config config.command = "unstake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -581,13 +523,9 @@ def test_unstake_with_exclude_hotkeys_from_all( self ): any_order = True ) - def test_unstake_with_multiple_hotkeys_max_stake( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_unstake_with_multiple_hotkeys_max_stake( self ): config = self.config config.command = "unstake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 5.0 # The keys should have at most 5.0 tao staked after @@ -660,13 +598,9 @@ def test_unstake_with_multiple_hotkeys_max_stake( self ): any_order = True ) - def test_unstake_with_multiple_hotkeys_max_stake_not_enough_stake( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_unstake_with_multiple_hotkeys_max_stake_not_enough_stake( self ): config = self.config config.command = "unstake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 5.0 # The keys should have at most 5.0 tao staked after @@ -747,13 +681,9 @@ def test_unstake_with_multiple_hotkeys_max_stake_not_enough_stake( self ): # We shouldn't unstake from hk1 as it has less than max_stake staked assert all(mock_wallet.hotkey_str != 'hk1' for mock_wallet in mock_wallets_) - def test_stake_with_specific_hotkeys( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_specific_hotkeys( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -818,13 +748,9 @@ def test_stake_with_specific_hotkeys( self ): any_order = True ) - def test_stake_with_all_hotkeys( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_all_hotkeys( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -870,13 +796,9 @@ def test_stake_with_all_hotkeys( self ): any_order = True ) - def test_stake_with_exclude_hotkeys_from_all( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_exclude_hotkeys_from_all( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True config.amount = 5.0 config.wallet.name = "fake_wallet" @@ -924,13 +846,9 @@ def test_stake_with_exclude_hotkeys_from_all( self ): any_order = True ) - def test_stake_with_multiple_hotkeys_max_stake( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_multiple_hotkeys_max_stake( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 15.0 # The keys should have at most 15.0 tao staked after @@ -1008,13 +926,9 @@ def test_stake_with_multiple_hotkeys_max_stake( self ): any_order = True ) - def test_stake_with_multiple_hotkeys_max_stake_not_enough_balance( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_multiple_hotkeys_max_stake_not_enough_balance( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 15.0 # The keys should have at most 15.0 tao staked after @@ -1099,13 +1013,9 @@ def test_stake_with_multiple_hotkeys_max_stake_not_enough_balance( self ): # We should not try to stake more than the mock_balance self.assertAlmostEqual(total_staked, mock_balance.tao, delta=0.001) - def test_stake_with_single_hotkey_max_stake( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_single_hotkey_max_stake( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 15.0 # The keys should have at most 15.0 tao staked after @@ -1181,13 +1091,9 @@ def test_stake_with_single_hotkey_max_stake( self ): any_order = True ) - def test_stake_with_single_hotkey_max_stake_not_enough_balance( self ): - bittensor.subtensor.register = MagicMock(return_value = True) - + def test_stake_with_single_hotkey_max_stake_not_enough_balance( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 15.0 # The keys should have at most 15.0 tao staked after @@ -1276,8 +1182,6 @@ def test_stake_with_single_hotkey_max_stake_enough_stake( self ): config = self.config config.command = "stake" - config.subtensor._mock = True - config.subtensor.network = "mock" config.no_prompt = True # Notie amount is not specified config.max_stake = 15.0 # The keys should have at most 15.0 tao staked after @@ -1354,13 +1258,10 @@ def test_stake_with_single_hotkey_max_stake_enough_stake( self ): def test_register( self ): - config = self.config - config.subtensor._mock = True config.command = "register" config.subtensor.register.num_processes = 1 config.subtensor.register.update_interval = 50_000 - config.subtensor.network = "mock" config.no_prompt = True config.no_version_checking = False @@ -1369,16 +1270,12 @@ def test_register( self ): cli.run() def test_stake( self ): - wallet = TestCli.generate_wallet() - bittensor.Subtensor.neuron_for_pubkey = MagicMock(return_value=self.mock_neuron) config = self.config - config.subtensor.network = "mock" - config.wallet._mock = True config.no_prompt = True - config.subtensor._mock = True config.command = "stake" config.amount = 0.5 config.stake_all = False + config.wallet._mock = True config.no_password = True config.no_version_checking = False @@ -1395,7 +1292,6 @@ def test_new_coldkey( self ): config.command = "new_coldkey" config.amount = 1 config.dest = "no_prompt" - config.subtensor._mock = True config.model = "core_server" config.n_words = 12 config.use_password = False @@ -1413,9 +1309,7 @@ def test_new_hotkey( self ): config.wallet.name = "new_hotkey_testwallet" config.command = "new_hotkey" config.amount = 1 - config.subtensor.network = "mock" config.dest = "no_prompt" - config.subtensor._mock = True config.model = "core_server" config.n_words = 12 config.use_password = False @@ -1431,9 +1325,7 @@ def test_regen_coldkey( self ): config.wallet.name = "regen_coldkey_testwallet" config.command = "regen_coldkey" config.amount = 1 - config.subtensor.network = "mock" config.dest = "no_prompt" - config.subtensor._mock = True config.model = "core_server" config.mnemonic = "faculty decade seven jelly gospel axis next radio grain radio remain gentle" config.seed = None @@ -1450,8 +1342,6 @@ def test_regen_coldkeypub( self ): config = self.config config.wallet.name = "regen_coldkeypub_testwallet" config.command = "regen_coldkeypub" - config.subtensor.network = "mock" - config.subtensor._mock = True config.ss58_address = "5DD26kC2kxajmwfbbZmVmxhrY9VeeyR1Gpzy9i8wxLUg6zxm" config.public_key = None config.use_password = False @@ -1467,8 +1357,6 @@ def test_regen_hotkey( self ): config.wallet.name = "regen_hotkey_testwallet" config.command = "regen_hotkey" config.amount = 1 - config.subtensor.network = "mock" - config.subtensor._mock = True config.model = "core_server" config.mnemonic = "faculty decade seven jelly gospel axis next radio grain radio remain gentle" config.seed = None @@ -1485,9 +1373,7 @@ def test_metagraph( self ): config = self.config config.wallet.name = "metagraph_testwallet" config.command = "metagraph" - config.subtensor.network = "mock" config.no_prompt = True - config.subtensor._mock = True config.no_version_checking = False cli = bittensor.cli(config) @@ -1497,11 +1383,9 @@ def test_set_weights( self ): config = self.config config.wallet.name = "set_weights_testwallet" - config.subtensor.network = "mock" config.no_prompt = True config.uids = [1, 2, 3, 4] config.weights = [0.25, 0.25, 0.25, 0.25] - config.subtensor._mock = True config.n_words = 12 config.use_password = False config.no_version_checking = False @@ -1522,9 +1406,7 @@ def test_set_weights( self ): def test_inspect( self ): config = self.config config.wallet.name = "inspect_testwallet" - config.subtensor.network = "mock" config.no_prompt = True - config.subtensor._mock = True config.n_words = 12 config.use_password = False config.overwrite_coldkey = True @@ -1585,9 +1467,7 @@ def test_list( self ): config = self.config config.wallet.path = 'tmp/walletpath' config.wallet.name = 'mock_wallet' - config.subtensor.network = "mock" config.no_prompt = True - config.subtensor._mock = True config.command = "list" config.no_version_checking = False @@ -1609,9 +1489,7 @@ def test_list_no_wallet( self ): )): config = self.config config.wallet.path = '/tmp/test_cli_test_list_no_wallet' - config.subtensor.network = "mock" config.no_prompt = True - config.subtensor._mock = True config.command = "list" config.no_version_checking = False @@ -1654,15 +1532,13 @@ class ExitEarlyException(Exception): base_args = [ "register", - "--subtensor._mock", - "--subtensor.network", "mock", "--wallet.path", "tmp/walletpath", "--wallet.name", "mock", "--wallet.hotkey", "hk0", "--no_prompt", "--cuda.dev_id", "0", ] - + bittensor.subtensor.check_config = MagicMock(return_value = True) with patch('torch.cuda.is_available', return_value=True): with patch('bittensor.Subtensor.register', side_effect=ExitEarlyException): # Should be able to set true without argument @@ -1703,8 +1579,6 @@ def test_run_reregister_false(self): '--wallet.name', 'mock', '--wallet.hotkey', 'mock_hotkey', '--wallet._mock', 'True', - '--subtensor.network', 'mock', - '--subtensor._mock', 'True', '--no_prompt', '--wallet.reregister', 'False' # Don't reregister ]) @@ -1731,8 +1605,6 @@ class MockException(Exception): '--wallet.name', 'mock', '--wallet.hotkey', 'mock_hotkey', '--wallet._mock', 'True', - '--subtensor.network', 'mock', - '--subtensor._mock', 'True', '--cuda.no_cuda', '--no_prompt', '--model', 'core_server', From ca409c20b39e597de2e0f308a58d274567c5a767 Mon Sep 17 00:00:00 2001 From: opentaco Date: Wed, 18 Jan 2023 12:33:00 +0200 Subject: [PATCH 7/8] Log prune_len and logits_divergence --- .../_neuron/text/core_validator/__init__.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index 1a74cb9dfc..5dd2eec2a2 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -987,7 +987,7 @@ def forward( num_endpoints = len(random_endpoints) # in case len(self.permute_uids) < num_endpoints during random_uids select logger.info(f'Forward \t| Routing forward [{time.time() - start_time:.3g}s]') - logger.info(f'Dendrite \t| Request {num_endpoints} x {list(inputs_seq.shape)}') + logger.info(f'Dendrite \t| Request {num_endpoints} x {list(inputs_seq.shape)} (prune_len={prune_len})') request_start_time = time.time() # === Define which synapse we want to use === @@ -1032,6 +1032,7 @@ def forward( validation_params = (random_uids, query_responses, return_ops, times, routing_score, inputs, val_len, self.loss_fct, self.config.nucleus.scaling_law_power, self.config.nucleus.synergy_scaling_law_power, + self.config.nucleus.logits_divergence, console_width, self.config.logging.debug or self.config.logging.trace) loss = torch.tensor(0.).to(self.device) # to accumulate neuron_loss and routing_loss over synapses @@ -1061,7 +1062,7 @@ def scaling_law_loss_to_params(loss): def textcausallm(uids: torch.Tensor, query_responses: List[List[torch.FloatTensor]], return_ops: List[torch.LongTensor], times: List[torch.FloatTensor], routing_score: torch.FloatTensor, inputs: torch.FloatTensor, validation_len: int, loss_fct: Callable, - scaling_law_power: float, synergy_scaling_law_power: float, + scaling_law_power: float, synergy_scaling_law_power: float, logits_divergence_penalty: float, console_width: int, logging, synapse: 'bittensor.TextCausalLM' = None, index_s: int = 0 ) -> Tuple[torch.FloatTensor, Dict]: r""" @@ -1088,6 +1089,8 @@ def textcausallm(uids: torch.Tensor, query_responses: List[List[torch.FloatTenso Power for modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. synergy_scaling_law_power (:obj:`float`, `required`): Power for synergy modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. + logits_divergence_penalty (:obj:`float`, `required`): + Penalty scaling for logits divergence. console_width (:obj:`int`, `required`): Config console width for table print. logging (:obj:`bool`, `required`): @@ -1139,7 +1142,7 @@ def _synergy(first, second, target, _ext): loss, stats, unsuccessful = shapley_base(uids, query_responses, return_ops, times, routing_score, _base_params, index_s, ext='') - logger.info(f'{str(synapse)} \t| Shapley base values (power={scaling_law_power:.1f})' + logger.info(f'{str(synapse)} \t| Shapley base values (power={scaling_law_power:.1f}) ' f'[{time.time() - shapley_start_time:.3g}s]') synergy_start_time = time.time() @@ -1166,7 +1169,7 @@ def _synergy(first, second, target, _ext): if hasattr(s[key], 'item'): s[key] = s[key].item() - logger.info(f'{str(synapse)} \t| Shapley synergy values (power={synergy_scaling_law_power:.1f})' + logger.info(f'{str(synapse)} \t| Shapley synergy values (power={synergy_scaling_law_power:.1f}) ' f'[{time.time() - synergy_start_time:.3g}s]') if logging: @@ -1188,7 +1191,7 @@ def _synergy(first, second, target, _ext): def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatTensor]], return_ops: List[torch.LongTensor], times: List[torch.FloatTensor], routing_score: torch.FloatTensor, inputs: torch.FloatTensor, validation_len: int, loss_fct: Callable, - scaling_law_power: float, synergy_scaling_law_power: float, + scaling_law_power: float, synergy_scaling_law_power: float, logits_divergence_penalty: float, console_width: int, logging, synapse: 'bittensor.TextCausalLMNext' = None, index_s: int = 0, ) -> Tuple[torch.FloatTensor, Dict]: r""" @@ -1215,6 +1218,8 @@ def textcausallmnext(uids: torch.Tensor, query_responses: List[List[torch.FloatT Power for modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. synergy_scaling_law_power (:obj:`float`, `required`): Power for synergy modified scaling law, powered down to improve dynamic range, e.g. 3 → 6 nats for 0.5. + logits_divergence_penalty (:obj:`float`, `required`): + Penalty scaling for logits divergence. console_width (:obj:`int`, `required`): Config console width for table print. logging (:obj:`bool`, `required`): @@ -1254,17 +1259,18 @@ def _synergy(first, second, target, ext): shapley_start_time = time.time() loss, stats, unsuccessful = shapley_base(uids, query_responses, return_ops, times, routing_score, _base_params, index_s, ext='_nxt') - logger.info(f'{str(synapse)} \t| Shapley base values (power={scaling_law_power:.1f})' + logger.info(f'{str(synapse)} \t| Shapley base values (power={scaling_law_power:.1f}) ' f'[{time.time() - shapley_start_time:.3g}s]') divergence_start_time = time.time() with torch.no_grad(): logits_divergence(stats, uids, query_responses, return_ops, times, index_s, ext='_nxt') - logger.info(f'{str(synapse)} \t| Logits divergences [{time.time() - divergence_start_time:.3g}s]') + logger.info(f'{str(synapse)} \t| Logits divergences (penalty={logits_divergence_penalty}) ' + f'[{time.time() - divergence_start_time:.3g}s]') synergy_start_time = time.time() syn_loss_diff = shapley_synergy(stats, _synergy, '_nxt', scaling_law_power=synergy_scaling_law_power) - logger.info(f'{str(synapse)} \t| Shapley synergy values (power={synergy_scaling_law_power:.1f})' + logger.info(f'{str(synapse)} \t| Shapley synergy values (power={synergy_scaling_law_power:.1f}) ' f'[{time.time() - synergy_start_time:.3g}s]') # === Shapley value combination === From 6ab38372163f5030c41d671d727a8bc41dfef835 Mon Sep 17 00:00:00 2001 From: opentaco Date: Wed, 18 Jan 2023 13:34:57 +0200 Subject: [PATCH 8/8] Always get latest prune_len --- bittensor/_neuron/text/core_validator/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/_neuron/text/core_validator/__init__.py b/bittensor/_neuron/text/core_validator/__init__.py index 5dd2eec2a2..3bcce2705d 100644 --- a/bittensor/_neuron/text/core_validator/__init__.py +++ b/bittensor/_neuron/text/core_validator/__init__.py @@ -401,7 +401,7 @@ def run_epoch( self ): sequence_length = self.subtensor.validator_sequence_length validation_len = self.config.neuron.validation_len # Number of tokens to holdout for phrase validation beyond sequence context # Number of tokens to prune for phrase validation beyond sequence context - prune_len = self.subtensor.prune_len if self.config.neuron.prune_len == -1 else self.config.neuron.prune_len + prune_len = self.config.neuron.prune_len = self.subtensor.prune_len min_allowed_weights = self.subtensor.min_allowed_weights max_weight_limit = self.subtensor.max_weight_limit blocks_per_epoch = self.subtensor.validator_epoch_length if self.config.neuron.blocks_per_epoch == -1 else self.config.neuron.blocks_per_epoch