Example #1
0
    def register(self,
                 wait_for_inclusion: bool = False,
                 wait_for_finalization: bool = True,
                 subtensor: 'bittensor.Subtensor' = None,
                 prompt: bool = False) -> 'bittensor.Wallet':
        """ Registers this wallet on the chain.
            Args:
                wait_for_inclusion (bool):
                    if set, waits for the extrinsic to enter a block before returning true, 
                    or returns false if the extrinsic fails to enter the block within the timeout.   
                wait_for_finalization (bool):
                    if set, waits for the extrinsic to be finalized on the chain before returning true,
                    or returns false if the extrinsic fails to be finalized within the timeout.
                subtensor( 'bittensor.Subtensor' ):
                    Bittensor subtensor connection. Overrides with defaults if None.
                prompt (bool):
                    If true, the call waits for confirmation from the user before proceeding.
            Return:
                This wallet.
        """
        # Get chain connection.
        if subtensor == None: subtensor = bittensor.subtensor()
        subtensor.register(wallet=self,
                           wait_for_inclusion=wait_for_inclusion,
                           wait_for_finalization=wait_for_finalization,
                           prompt=prompt)

        return self
Example #2
0
    def inspect ( self ):
        r""" Inspect a cold, hot pair.
        """
        wallet = bittensor.wallet(config = self.config)
        subtensor = bittensor.subtensor( config = self.config )
        dendrite = bittensor.dendrite( wallet = wallet )

        
        with bittensor.__console__.status(":satellite: Looking up account on: [white]{}[/white] ...".format(self.config.subtensor.network)):
            
            if self.config.wallet.hotkey == 'None':
                wallet.coldkeypub
                cold_balance = wallet.balance
                bittensor.__console__.print("\n[bold white]{}[/bold white]:\n  {}[bold white]{}[/bold white]\n {} {}\n".format( wallet, "coldkey:".ljust(15), wallet.coldkeypub.ss58_address, " balance:".ljust(15), cold_balance.__rich__()), highlight=True)

            else:
                wallet.hotkey
                wallet.coldkeypub
                neuron = subtensor.neuron_for_pubkey( ss58_hotkey = wallet.hotkey.ss58_address )
                endpoint = bittensor.endpoint.from_neuron( neuron )
                if neuron.is_null:
                    registered = '[bold white]No[/bold white]'
                    stake = bittensor.Balance.from_tao( 0 )
                    emission = bittensor.Balance.from_rao( 0 )
                    latency = 'N/A'
                else:
                    registered = '[bold white]Yes[/bold white]'
                    stake = bittensor.Balance.from_tao( neuron.stake )
                    emission = bittensor.Balance.from_rao( neuron.emission * 1000000000 )
                    _, c, t = dendrite.forward_text( endpoints = endpoint, inputs = 'hello world')
                    latency = "{}".format(t.tolist()[0]) if c.tolist()[0] == 1 else 'N/A'

                cold_balance = wallet.balance
                bittensor.__console__.print("\n[bold white]{}[/bold white]:\n  [bold grey]{}[bold white]{}[/bold white]\n  {}[bold white]{}[/bold white]\n  {}{}\n  {}{}\n  {}{}\n  {}{}\n  {}{}[/bold grey]".format( wallet, "coldkey:".ljust(15), wallet.coldkeypub.ss58_address, "hotkey:".ljust(15), wallet.hotkey.ss58_address, "registered:".ljust(15), registered, "balance:".ljust(15), cold_balance.__rich__(), "stake:".ljust(15), stake.__rich__(), "emission:".ljust(15), emission.__rich_rao__(), "latency:".ljust(15), latency ), highlight=True)
Example #3
0
    def weights(self):
        r""" Prints an weights to screen.
        """
        console = bittensor.__console__
        subtensor = bittensor.subtensor( config = self.config )
        metagraph = bittensor.metagraph( subtensor = subtensor )
        wallet = bittensor.wallet( config = self.config )
        with console.status(":satellite: Syncing with chain: [white]{}[/white] ...".format(self.config.subtensor.network)):
            metagraph.load()
            metagraph.sync()
            metagraph.save()

        table = Table()
        rows = []
        table.add_column("[bold white]uid", style='white', no_wrap=False)
        for uid in metagraph.uids.tolist():
            table.add_column("[bold white]{}".format(uid), style='white', no_wrap=False)
            if self.config.all_weights:
                rows.append(["[bold white]{}".format(uid) ] + ['{:.3f}'.format(v) for v in metagraph.W[uid].tolist()])
            else:
                if metagraph.coldkeys[uid] == wallet.coldkeypub.ss58_address:
                    if not self.config.all_hotkeys:
                        if metagraph.hotkeys[uid] == wallet.hotkey.ss58_address:
                            rows.append(["[bold white]{}".format(uid) ] + ['{:.3f}'.format(v) for v in metagraph.W[uid].tolist()])
                    else:
                        rows.append(["[bold white]{}".format(uid) ] + ['{:.3f}'.format(v) for v in metagraph.W[uid].tolist()])

        for row in rows:
            table.add_row(*row)
        table.box = None
        table.pad_edge = False
        table.width = None
        with console.pager():
            console.print(table)
Example #4
0
 def __new__(
     cls,
     config: 'bittensor.config' = None,
     subtensor: 'bittensor.Subtensor' = None,
     network: str = None,
     chain_endpoint: str = None,
 ) -> 'bittensor.Metagraph':
     r""" Creates a new bittensor.Metagraph object from passed arguments.
         Args:
             config (:obj:`bittensor.Config`, `optional`): 
                 bittensor.metagraph.config()
             subtensor (:obj:`bittensor.Subtensor`, `optional`): 
                 bittensor subtensor chain connection.
             network (default='nakamoto', type=str)
                 The subtensor network flag. The likely choices are:
                         -- nobunaga (staging network)
                         -- akatsuki (testing network)
                         -- nakamoto (main network)
                 If this option is set it overloads subtensor.chain_endpoint with 
                 an entry point node from that network.
             chain_endpoint (default=None, type=str)
                 The subtensor endpoint flag. If set, overrides the network argument.
     """
     if config == None:
         config = metagraph.config()
     config = copy.deepcopy(config)
     if subtensor == None:
         subtensor = bittensor.subtensor(network=network,
                                         chain_endpoint=chain_endpoint)
     return metagraph_impl.Metagraph(subtensor=subtensor)
Example #5
0
 def remove_stake(
     self,
     amount: Union[float, bittensor.Balance] = None,
     wait_for_inclusion: bool = False,
     wait_for_finalization: bool = True,
     subtensor: 'bittensor.Subtensor' = None,
     prompt: bool = False,
 ) -> bool:
     """ Removes stake from this wallet's hotkey and moves them onto it's coldkey balance.
         Args:
             amount_tao (float):
                 amount of tao to unstake or bittensor balance object. If None, unstakes all available hotkey balance.
             wait_for_inclusion (bool):
                 if set, waits for the extrinsic to enter a block before returning true, 
                 or returns false if the extrinsic fails to enter the block within the timeout.   
             wait_for_finalization (bool):
                 if set, waits for the extrinsic to be finalized on the chain before returning true,
                 or returns false if the extrinsic fails to be finalized within the timeout.
             subtensor( `bittensor.Subtensor` ):
                 Bittensor subtensor connection. Overrides with defaults if None.
             prompt (bool):
                 If true, the call waits for confirmation from the user before proceeding.
         Returns:
             success (bool):
                 flag is true if extrinsic was finalized or uncluded in the block. 
                 If we did not wait for finalization / inclusion, the response is true.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     return subtensor.unstake(wallet=self,
                              amount=amount,
                              wait_for_inclusion=wait_for_inclusion,
                              wait_for_finalization=wait_for_finalization,
                              prompt=prompt)
Example #6
0
 def setUp(self):
     self.subtensor = bittensor.subtensor( network = 'nobunaga' )
     self.wallet = bittensor.wallet()
     coldkey = Keypair.create_from_mnemonic(Keypair.generate_mnemonic())
     self.wallet.set_coldkey(coldkey, encrypt=False, overwrite=True)
     self.wallet.set_coldkeypub(coldkey, encrypt=False, overwrite=True)
     self.wallet.set_hotkey(Keypair.create_from_mnemonic(Keypair.generate_mnemonic()), encrypt=False, overwrite=True)
     self.mock_neuron = self.subtensor._neuron_dict_to_namespace(
         dict({
             "version":1,
             "ip":0,
             "port":0,
             "ip_type":0,
             "uid":1,
             "modality":0,
             "hotkey":'some_hotkey',
             "coldkey":'some_coldkey',
             "active":0,
             "last_update":0,
             "priority":0,
             "stake":1000000000000.0,
             "rank":0.0,
             "trust":0.0,
             "consensus":0.0,
             "incentive":0.0,
             "dividends":0.0,
             "emission":0.0,
             "bonds":[],
             "weights":[],
             "is_null":False
         })
     )
     self.neurons = self.subtensor.neurons()
     self.balance = Balance.from_tao(1000)
     assert True
Example #7
0
 def set_weights( self ):
     r""" Set weights and uids on chain.
     """
     wallet = bittensor.wallet( config = self.config )
     subtensor = bittensor.subtensor( config = self.config )
     subtensor.set_weights( 
         wallet, 
         uids = self.config.uids,
         weights = self.config.weights,
         wait_for_inclusion = True, 
         prompt = not self.config.no_prompt 
     )
Example #8
0
 def is_registered(self, subtensor: 'bittensor.Subtensor' = None) -> bool:
     """ Returns true if this wallet is registered.
         Args:
             subtensor( 'bittensor.Subtensor' ):
                 Bittensor subtensor connection. Overrides with defaults if None.
                 Determines which network we check for registration.
         Return:
             is_registered (bool):
                 Is the wallet registered on the chain.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     return subtensor.is_hotkey_registered(self.hotkey.ss58_address)
Example #9
0
 def get_balance(
         self,
         subtensor: 'bittensor.Subtensor' = None) -> 'bittensor.Balance':
     """ Returns this wallet's coldkey balance from passed subtensor connection.
         Args:
             subtensor( 'bittensor.Subtensor' ):
                 Bittensor subtensor connection. Overrides with defaults if None.
         Return:
             balance (bittensor.utils.balance.Balance):
                 Coldkey balance.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     return subtensor.get_balance(address=self.coldkeypub.ss58_address)
Example #10
0
 def __init__( self, config: 'bittensor.config', nucleus: 'Nucleus'):
     r""" Initializes the neuron with the passed config.
     """
     self.config = config
     self.wallet = bittensor.wallet ( config = self.config )
     self.subtensor = bittensor.subtensor ( config = self.config )
     self.metagraph = bittensor.metagraph ( config = self.config, subtensor = self.subtensor )
     self.dendrite = bittensor.dendrite ( config = self.config, wallet = self.wallet )
     self.dataset = bittensor.dataset ( config = self.config )
     self.axon = bittensor.axon (
         config = self.config,
         wallet = self.wallet,
         forward_text = self.forward_text,
         backward_text = self.backward_text,
         blacklist = self.blacklist,
     )
     self.device = torch.device( device = self.config.neuron.device )
     self.nucleus = nucleus.to(self.device)
     self.nucleus.metagraph = self.metagraph_callback
     self.nucleus.dendrite = self.dendrite
     self.optimizer = torch.optim.SGD(
         [ {'params': self.nucleus.peer_weights, 'lr': self.config.neuron.learning_rate_chain} ],
         lr = self.config.neuron.learning_rate,
         momentum = self.config.neuron.momentum,
     )
     self.scheduler = torch.optim.lr_scheduler.StepLR(self.optimizer,
         step_size = 1.0,
         gamma = 0.95
     )
     self.stats = SimpleNamespace(
         global_step = 0,
         last_sync_block = 0,
         epoch_data_size = 0,
         epoch_sync_count = 0,
         local_target_epoch_loss = math.inf,
         distillation_epoch_loss = math.inf,
         remote_target_epoch_loss = math.inf,
         local_epoch_acc = 0,
         best_epoch_loss = math.inf,
         scores = torch.nn.Parameter(torch.zeros(0), requires_grad = False).to(self.device),
         ema_scores = torch.nn.Parameter(torch.zeros(0), requires_grad = False).to(self.device)
     )
     # ---- Decay factor for fisher ema score 
     self.fisher_ema_decay = 0.995
Example #11
0
 def get_uid(self, subtensor: 'bittensor.Subtensor' = None) -> int:
     """ Returns this wallet's hotkey uid or -1 if the hotkey is not subscribed.
         Args:
             subtensor( 'bittensor.Subtensor' ):
                 Bittensor subtensor connection. Overrides with defaults if None.
         Return:
             uid (int):
                 Network uid or -1 if you are not registered.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     if not self.is_registered(subtensor=subtensor):
         print(
             colored(
                 'This wallet is not registered. Call wallet.register() before this function.',
                 'red'))
         return -1
     neuron = self.get_neuron(subtensor=subtensor)
     if neuron.is_null:
         return -1
     else:
         return neuron.uid
Example #12
0
 def get_neuron(
     self,
     subtensor: 'bittensor.Subtensor' = None
 ) -> Union[SimpleNamespace, None]:
     """ Returns this wallet's neuron information from subtensor.
         Args:
             subtensor( 'bittensor.Subtensor' ):
                 Bittensor subtensor connection. Overrides with defaults if None.
         Return:
             neuron (Union[ SimpleNamespace, None ]):
                 neuron account on the chain or None if you are not registered.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     if not self.is_registered(subtensor=subtensor):
         print(
             colored(
                 'This wallet is not registered. Call wallet.register() before this function.',
                 'red'))
         return None
     neuron = subtensor.neuron_for_wallet(self)
     return neuron
Example #13
0
 def transfer(
     self,
     dest: str,
     amount: Union[float, bittensor.Balance],
     wait_for_inclusion: bool = False,
     wait_for_finalization: bool = True,
     subtensor: 'bittensor.Subtensor' = None,
     prompt: bool = False,
 ) -> bool:
     """ Transfers Tao from this wallet's coldkey to the destination address.
         Args:
             dest (`type`:str, required):
                 The destination address either encoded as a ss58 or ed255 public-key string of 
                 secondary account.
             amount (float, required):
                 amount of tao to transfer or a bittensor balance object.
             wait_for_inclusion (bool):
                 if set, waits for the extrinsic to enter a block before returning true, 
                 or returns false if the extrinsic fails to enter the block within the timeout.   
             wait_for_finalization (bool):
                 if set, waits for the extrinsic to be finalized on the chain before returning true,
                 or returns false if the extrinsic fails to be finalized within the timeout.
             subtensor( `bittensor.Subtensor` ):
                 Bittensor subtensor connection. Overrides with defaults if None.
             prompt (bool):
                 If true, the call waits for confirmation from the user before proceeding.
         Returns:
             success (bool):
                 flag is true if extrinsic was finalized or uncluded in the block. 
                 If we did not wait for finalization / inclusion, the response is true.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     return subtensor.transfer(wallet=self,
                               dest=dest,
                               amount=amount,
                               wait_for_inclusion=wait_for_inclusion,
                               wait_for_finalization=wait_for_finalization,
                               prompt=prompt)
Example #14
0
 def get_stake(
         self,
         subtensor: 'bittensor.Subtensor' = None) -> 'bittensor.Balance':
     """ Returns this wallet's staking balance from passed subtensor connection.
         Args:
             subtensor( 'bittensor.Subtensor' ):
                 Bittensor subtensor connection. Overrides with defaults if None.
         Return:
             balance (bittensor.utils.balance.Balance):
                 Stake account balance.
     """
     if subtensor == None: subtensor = bittensor.subtensor()
     if not self.is_registered(subtensor=subtensor):
         print(
             colored(
                 'This wallet is not registered. Call wallet.register() before this function.',
                 'red'))
         return bittensor.Balance(0)
     neuron = self.get_neuron(subtensor=subtensor)
     if neuron.is_null:
         return bittensor.Balance(0)
     else:
         return bittensor.Balance.from_tao(neuron.stake)
Example #15
0
    def __init__(self, config: 'bittensor.config' = None):
        if config == None: config = neuron.config()
        config = config
        self.check_config(config)
        bittensor.logging(
            config=config,
            logging_dir=config.neuron.full_path,
        )
        self.config = config
        print(config)

        # Load/Create our bittensor wallet.
        self.wallet = bittensor.wallet(config=config).create().register()

        # Connect to the chain.
        self.subtensor = bittensor.subtensor(config=config)

        # Load/Sync/Save our metagraph.
        self.metagraph = bittensor.metagraph(
            subtensor=self.subtensor).load().sync().save()

        self.uid = self.metagraph.hotkeys.index(
            self.wallet.hotkey.ss58_address)

        # Create Dendrite.
        self.dendrite = bittensor.dendrite(config=config)

        # Load genesis dataset.
        self.dataset = bittensor.dataset(config=config)

        # Build Device.
        self.device = torch.device(device=config.neuron.device)

        self.nucleus = Validator(config=config,
                                 metagraph=self.metagraph_callback,
                                 dendrite=self.dendrite,
                                 device=self.device)
Example #16
0
    def overview(self):
        r""" Prints an overview for the wallet's colkey.
        """
        console = bittensor.__console__
        wallet = bittensor.wallet( config = self.config )
        subtensor = bittensor.subtensor( config = self.config )
        all_hotkeys = CLI._get_hotkey_wallets_for_wallet( wallet )
        neurons = []
        block = subtensor.block
        with console.status(":satellite: Syncing with chain: [white]{}[/white] ...".format(self.config.subtensor.network)):
            for wallet in tqdm(all_hotkeys):
                nn = subtensor.neuron_for_pubkey( wallet.hotkey.ss58_address )
                if not nn.is_null:
                    neurons.append( nn )
            balance = subtensor.get_balance( wallet.coldkeypub.ss58_address )

        TABLE_DATA = []  
        total_stake = 0.0
        total_rank = 0.0
        total_trust = 0.0
        total_consensus = 0.0
        total_incentive = 0.0
        total_dividends = 0.0
        total_emission = 0     
        for nn, hotwallet in tqdm(list(zip(neurons,all_hotkeys))):
            uid = nn.uid
            active = nn.active
            stake = nn.stake
            rank = nn.rank
            trust = nn.trust
            consensus = nn.consensus
            incentive = nn.incentive
            dividends = nn.dividends
            emission = int(nn.emission * 1000000000)
            last_update = int(block -  nn.last_update)
            row = [
                hotwallet.hotkey_str,
                str(uid), 
                str(active), 
                '{:.5f}'.format(stake),
                '{:.5f}'.format(rank), 
                '{:.5f}'.format(trust), 
                '{:.5f}'.format(consensus), 
                '{:.5f}'.format(incentive),
                '{:.5f}'.format(dividends),
                '{}'.format(emission),
                str(last_update),
                bittensor.utils.networking.int_to_ip( nn.ip) + ':' + str(nn.port) if nn.port != 0 else '[yellow]none[/yellow]', 
                nn.hotkey
            ]
            total_stake += stake
            total_rank += rank
            total_trust += trust
            total_consensus += consensus
            total_incentive += incentive
            total_dividends += dividends
            total_emission += emission
            TABLE_DATA.append(row)
            
        total_neurons = len(neurons)                
        table = Table(show_footer=False)
        table.title = (
            "[white]Wallet - {}:{}".format(self.config.wallet.name, wallet.coldkeypub.ss58_address)
        )
        table.add_column("[overline white]HOTKEY",  str(total_neurons), footer_style = "overline white", style='bold white')
        table.add_column("[overline white]UID",  str(total_neurons), footer_style = "overline white", style='yellow')
        table.add_column("[overline white]ACTIVE", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]STAKE(\u03C4)", '\u03C4{:.5f}'.format(total_stake), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]RANK", '{:.5f}'.format(total_rank), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]TRUST", '{:.5f}'.format(total_trust), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]CONSENSUS", '{:.5f}'.format(total_consensus), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]INCENTIVE", '{:.5f}'.format(total_incentive), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]DIVIDENDS", '{:.5f}'.format(total_dividends), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]EMISSION(\u03C1)", '\u03C1{}'.format(int(total_emission)), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]UPDATED", justify='right', no_wrap=True)
        table.add_column("[overline white]AXON", justify='left', style='dim blue', no_wrap=True) 
        table.add_column("[overline white]HOTKEY", style='dim blue', no_wrap=False)
        table.show_footer = True
        table.caption = "[white]Wallet balance: [green]\u03C4" + str(balance.tao)

        console.clear()
        for row in TABLE_DATA:
            table.add_row(*row)
        table.box = None
        table.pad_edge = False
        table.width = None
        console.print(table)
Example #17
0
 def test_network_overrides( self ):
     config = bittensor.subtensor.config()
     subtensor = bittensor.subtensor(network='nobunaga', config=config, )
     assert subtensor.endpoint_for_network() in bittensor.__nobunaga_entrypoints__
Example #18
0
def setup_subtensor(port: int):
    chain_endpoint = "localhost:{}".format(port)
    subtensor = bittensor.subtensor(chain_endpoint=chain_endpoint, )
    return subtensor, port
Example #19
0
 def register( self ):
     r""" Register neuron.
     """
     wallet = bittensor.wallet( config = self.config )
     subtensor = bittensor.subtensor( config = self.config )
     subtensor.register( wallet = wallet, prompt = not self.config.no_prompt)
Example #20
0
 def transfer( self ):
     r""" Transfer token of amount to destination.
     """
     wallet = bittensor.wallet( config = self.config )
     subtensor = bittensor.subtensor( config = self.config )
     subtensor.transfer( wallet = wallet, dest = self.config.dest, amount = self.config.amount, wait_for_inclusion = True, prompt = not self.config.no_prompt )
Example #21
0
def serve(config, model):
    config.to_defaults()

    # Create Subtensor connection
    subtensor = bittensor.subtensor(config=config)

    # Load/Create our bittensor wallet.
    wallet = bittensor.wallet(config=config).create().register()

    # Load/Sync/Save our metagraph.
    metagraph = bittensor.metagraph(subtensor=bittensor.subtensor(
        config=config)).load().sync().save()

    # Create our optimizer.
    optimizer = torch.optim.SGD(
        [{
            "params": model.parameters()
        }],
        lr=config.neuron.learning_rate,
        momentum=config.neuron.momentum,
    )
    mutex = Lock()

    def forward_text(inputs_x):
        r""" Single threaded version of the Forward function that is called when the axon recieves a forward request from other peers
        """
        return model.encode_forward(inputs_x)

    def backward_text(inputs_x, grads_dy):
        r"""Single threaded backwards function that is called when the axon recieves a backwards request from other peers.
            Updates the server parameters with gradients through the chain.             
        """
        if config.neuron.training:
            with mutex:
                with torch.enable_grad():
                    with torch.autograd.set_detect_anomaly(True):
                        outputs_y = model.encode_forward(inputs_x)
                        torch.autograd.backward(tensors=[outputs_y],
                                                grad_tensors=[grads_dy])
                        optimizer.step()
                        optimizer.zero_grad()

    # Create our axon server and subscribe it to the network.
    axon = bittensor.axon(
        wallet=wallet,
        forward_text=forward_text,
        backward_text=backward_text,
    ).start().serve(subtensor=subtensor)

    if config.wandb.api_key != 'default':
        # --- Init Wandb.
        bittensor.wandb(config=config,
                        cold_pubkey=wallet.coldkeypub.ss58_address,
                        hot_pubkey=wallet.hotkey.ss58_address,
                        root_dir=config.neuron.full_path)

    last_set_block = subtensor.get_current_block()

    # --- Run Forever.
    while True:

        current_block = subtensor.get_current_block()
        end_block = current_block + config.neuron.blocks_per_epoch
        while end_block >= current_block:
            time.sleep(bittensor.__blocktime__)
            current_block = subtensor.get_current_block()

        nn = subtensor.neuron_for_pubkey(wallet.hotkey.ss58_address)
        uid = metagraph.hotkeys.index(wallet.hotkey.ss58_address)
        wandb_data = {
            'stake': nn.stake,
            'rank': nn.rank,
            'trust': nn.trust,
            'consensus': nn.consensus,
            'incentive': nn.incentive,
            'emission': nn.emission,
        }
        bittensor.__console__.print('[green]Current Status:[/green]',
                                    wandb_data)
        if config.wandb.api_key != 'default':

            df = pandas.concat([
                bittensor.utils.indexed_values_to_dataframe(
                    prefix='w_i_{}'.format(nn.uid),
                    index=metagraph.uids,
                    values=metagraph.W[:, uid]),
                axon.to_dataframe(metagraph=metagraph),
            ],
                               axis=1)
            df['uid'] = df.index
            wandb_info_axon = axon.to_wandb()
            wandb.log({**wandb_data, **wandb_info_axon}, step=current_block)
            wandb.log({'stats': wandb.Table(dataframe=df)}, step=current_block)

        if current_block - last_set_block > config.neuron.blocks_per_set_weights:
            try:
                last_set_block = current_block
                # Set self weights to maintain activity.
                chain_weights = torch.zeros(metagraph.n)
                chain_weights[uid] = 1
                did_set = subtensor.set_weights(
                    uids=metagraph.uids,
                    weights=chain_weights,
                    wait_for_inclusion=False,
                    wallet=wallet,
                )

                if did_set:
                    logger.success('Successfully set weights on the chain')
                else:
                    logger.error('Failed to set weights on chain. (Timeout)')
            except Exception as e:
                logger.error('Failure setting weights on chain with error: {}',
                             e)
Example #22
0
def serve(config, gp_server):
    config.to_defaults()

    # Create Subtensor connection
    subtensor = bittensor.subtensor(config=config)

    # Load/Create our bittensor wallet.
    wallet = bittensor.wallet(config=config).create().register()

    # Load/Sync/Save our metagraph.
    metagraph = bittensor.metagraph(subtensor=subtensor).load().sync().save()

    # Instantiate the model we are going to serve on the network.
    # Creating a threading lock for updates to the model
    mutex = Lock()
    gp_server = gp_server.to(gp_server.device)

    # Create our optimizer.
    optimizer = torch.optim.SGD(
        [{
            "params": gp_server.parameters()
        }],
        lr=config.neuron.learning_rate,
        momentum=config.neuron.momentum,
    )

    timecheck = {}

    # Define our forward function.
    def forward_text(inputs_x):
        r""" Forward function that is called when the axon recieves a forward request from other peers
            Args:
                inputs_x ( :obj:`torch.Tensor`, `required`):
                    torch inputs to be forward processed.

            Returns:
                outputs (:obj:`torch.FloatTensor`):
                    The nucleus's outputs as a torch tensor of shape [batch_size, sequence_len, __network_dim__]
        """
        return gp_server.encode_forward(inputs_x.to(gp_server.device))

    # Define our backward function.
    def backward_text(inputs_x, grads_dy):
        r"""Backwards function that is called when the axon recieves a backwards request from other peers.
            Updates the server parameters with gradients through the chain.

            Args:
                inputs_x ( :obj:`torch.Tensor`, `required`):
                    torch inputs from previous forward call.
                grads_dy ( :obj:`torch.Tensor`, `required`):
                    torch grads of forward output.
                    
        """
        # -- normalized grads --
        grads_dy = grads_dy / (grads_dy.sum() + 0.00001)

        with mutex:
            outputs_y = gp_server.encode_forward(inputs_x.to(gp_server.device))
            with torch.autograd.set_detect_anomaly(True):
                torch.autograd.backward(
                    tensors=[outputs_y],
                    grad_tensors=[grads_dy.to(gp_server.device)],
                    retain_graph=True)
            logger.info('Backwards axon gradient applied')

        gp_server.backward_gradients += inputs_x.size(0)

    def priority(pubkey: str, request_type: bittensor.proto.RequestType,
                 inputs_x) -> float:
        r"""Calculates the priority on requests based on stake and size of input

            Args:
                pubkey ( str, `required`):
                    The public key of the caller.
                inputs_x ( :obj:`torch.Tensor`, `required`):
                    torch inputs to be forward processed.
                request_type ( bittensor.proto.RequestType, `required`):
                    the request type ('FORWARD' or 'BACKWARD').
        """
        uid = metagraph.hotkeys.index(pubkey)
        priority = metagraph.S[uid].item() / sys.getsizeof(inputs_x)

        return priority

    def blacklist(pubkey: str,
                  request_type: bittensor.proto.RequestType) -> bool:
        r"""Axon security blacklisting, used to blacklist message from low stake members
            Args:
                pubkey ( str, `required`):
                    The public key of the caller.
                request_type ( bittensor.proto.RequestType, `required`):
                    the request type ('FORWARD' or 'BACKWARD').
        """

        # Check for stake
        def stake_check() -> bool:
            # If we allow non-registered requests return False = not blacklisted.
            is_registered = pubkey in metagraph.hotkeys
            if not is_registered:
                if config.neuron.blacklist_allow_non_registered:
                    return False
                else:
                    return True

            # Check stake.
            uid = metagraph.hotkeys.index(pubkey)
            if request_type == bittensor.proto.RequestType.FORWARD:
                if metagraph.S[uid].item(
                ) < config.neuron.blacklist.stake.forward:
                    return True
                else:
                    return False

            elif request_type == bittensor.proto.RequestType.BACKWARD:
                if metagraph.S[uid].item(
                ) < config.neuron.blacklist.stake.backward:
                    return True
                else:
                    return False

        # Check for time
        def time_check():
            current_time = datetime.now()
            if pubkey in timecheck.keys():
                prev_time = timecheck[pubkey]
                if current_time - prev_time >= timedelta(
                        seconds=config.neuron.blacklist.time):
                    timecheck[pubkey] = current_time
                    return False
                else:
                    timecheck[pubkey] = current_time
                    return True
            else:
                timecheck[pubkey] = current_time
                return False

        # Black list or not
        if stake_check() or time_check():
            return True
        else:
            return False

    # Create our axon server
    axon = bittensor.axon(wallet=wallet,
                          forward_text=forward_text,
                          backward_text=backward_text,
                          blacklist=blacklist,
                          priority=priority)

    # Training Data
    dataset = bittensor.dataset(config=config)

    # load our old model
    if config.neuron.no_restart != True:
        gp_server.load(config.neuron.full_path)

    if config.wandb.api_key != 'default':
        # --- Init Wandb.
        bittensor.wandb(config=config,
                        cold_pubkey=wallet.coldkeypub.ss58_address,
                        hot_pubkey=wallet.hotkey.ss58_address,
                        root_dir=config.neuron.full_path)

    nn = subtensor.neuron_for_pubkey(wallet.hotkey.ss58_address)

    # --- last sync block
    last_sync_block = subtensor.get_current_block()
    last_set_block = last_sync_block

    # -- Main Training loop --
    try:
        # -- download files from the mountain
        data = next(dataset)

        # --- creating our chain weights
        chain_weights = torch.zeros(metagraph.n)
        uid = nn.uid
        chain_weights[uid] = 1

        # --  serve axon to the network.
        axon.start().serve(subtensor=subtensor)

        while True:
            # --- Run
            current_block = subtensor.get_current_block()
            end_block = current_block + config.neuron.blocks_per_epoch
            interation = 0

            # --- Training step.
            while end_block >= current_block:
                if current_block != subtensor.get_current_block():
                    loss, _ = gp_server(next(dataset).to(gp_server.device))
                    if interation > 0:
                        losses += loss
                    else:
                        losses = loss
                    interation += 1
                    current_block = subtensor.get_current_block()

            #Custom learning rate
            if gp_server.backward_gradients > 0:
                optimizer.param_groups[0]['lr'] = 1 / (
                    gp_server.backward_gradients)
            else:
                optimizer.param_groups[0]['lr'] = 0.1

            # --- Update parameters
            if interation != 0 or gp_server.backward_gradients != 0:
                with mutex:
                    logger.info('Backpropagation Started')
                    if interation != 0:
                        losses.backward()
                    clip_grad_norm_(gp_server.parameters(), 1.0)

                    optimizer.step()
                    optimizer.zero_grad()
                    logger.info('Backpropagation Successful: Model updated')

            nn = subtensor.neuron_for_pubkey(wallet.hotkey.ss58_address)

            gp_server.backward_gradients = 0
            # --- logging data
            wandb_data = {
                'block': end_block,
                'loss': losses.cpu().item() / interation,
                'stake': nn.stake,
                'rank': nn.rank,
                'incentive': nn.incentive,
                'trust': nn.trust,
                'consensus': nn.consensus,
                'incentive': nn.incentive,
                'dividends': nn.dividends,
                'emission': nn.emission,
            }
            bittensor.__console__.print('[green]Current Status:[/green]',
                                        wandb_data)

            # Add additional wandb data for axon, metagraph etc.
            if config.wandb.api_key != 'default':

                df = pandas.concat([
                    bittensor.utils.indexed_values_to_dataframe(
                        prefix='w_i_{}'.format(nn.uid),
                        index=metagraph.uids,
                        values=metagraph.W[:, uid]),
                    bittensor.utils.indexed_values_to_dataframe(
                        prefix='s_i'.format(nn.uid),
                        index=metagraph.uids,
                        values=metagraph.S),
                    axon.to_dataframe(metagraph=metagraph),
                ],
                                   axis=1)
                df['uid'] = df.index
                stats_data_table = wandb.Table(dataframe=df)
                wandb_info_axon = axon.to_wandb()
                wandb.log({
                    **wandb_data,
                    **wandb_info_axon
                },
                          step=current_block)
                wandb.log({'stats': stats_data_table}, step=current_block)
                wandb.log({
                    'axon_query_times':
                    wandb.plot.scatter(stats_data_table,
                                       "uid",
                                       "axon_query_time",
                                       title="Axon Query time by UID")
                })
                wandb.log({
                    'in_weights':
                    wandb.plot.scatter(stats_data_table,
                                       "uid",
                                       'w_i_{}'.format(nn.uid),
                                       title="Inward weights by UID")
                })
                wandb.log({
                    'stake':
                    wandb.plot.scatter(stats_data_table,
                                       "uid",
                                       's_i',
                                       title="Stake by UID")
                })

            # Save the model
            gp_server.save(config.neuron.full_path)

            if current_block - last_set_block > config.neuron.blocks_per_set_weights:

                # --- Setting weights
                try:
                    last_set_block = current_block
                    # Set self weights to maintain activity.
                    chain_weights = torch.zeros(metagraph.n)
                    chain_weights[uid] = 1
                    did_set = subtensor.set_weights(
                        uids=metagraph.uids,
                        weights=chain_weights,
                        wait_for_inclusion=False,
                        wallet=wallet,
                    )

                    if did_set:
                        logger.success('Successfully set weights on the chain')
                    else:
                        logger.error(
                            'Failed to set weights on chain. (Timeout)')
                except Exception as e:
                    logger.error(
                        'Failure setting weights on chain with error: {}', e)

            if current_block - last_sync_block > config.neuron.metagraph_sync:
                metagraph.sync()
                last_sync_block = current_block

    except KeyboardInterrupt:
        # --- User ended session ----
        axon.stop()
    except Exception as e:
        # --- Unknown error ----
        logger.exception('Unknown exception: {} with traceback {}', e,
                         traceback.format_exc())
Example #23
0
 def stake( self ):
     r""" Stake token of amount to uid.
     """
     wallet = bittensor.wallet( config = self.config )
     subtensor = bittensor.subtensor( config = self.config )
     subtensor.add_stake( wallet, amount = None if self.config.stake_all else self.config.amount, wait_for_inclusion = True, prompt = not self.config.no_prompt )
Example #24
0
    def metagraph(self):
        r""" Prints an entire metagraph.
        """
        console = bittensor.__console__
        subtensor = bittensor.subtensor( config = self.config )
        metagraph = bittensor.metagraph( subtensor = subtensor )
        console.print(":satellite: Syncing with chain: [white]{}[/white] ...".format(self.config.subtensor.network))
        metagraph.sync()
        metagraph.save()
        issuance = subtensor.total_issuance
        difficulty = subtensor.difficulty

        TABLE_DATA = [] 
        total_stake = 0.0
        total_rank = 0.0
        total_trust = 0.0
        total_consensus = 0.0
        total_incentive = 0.0
        total_dividends = 0.0
        total_emission = 0  
        for uid in metagraph.uids:
            ep = metagraph.endpoint_objs[uid]
            row = [
                str(ep.uid), 
                '{:.5f}'.format( metagraph.stake[uid]),
                '{:.5f}'.format( metagraph.ranks[uid]), 
                '{:.5f}'.format( metagraph.trust[uid]), 
                '{:.5f}'.format( metagraph.consensus[uid]), 
                '{:.5f}'.format( metagraph.incentive[uid]),
                '{:.5f}'.format( metagraph.dividends[uid]),
                '{}'.format( int(metagraph.emission[uid] * 1000000000)),
                str((metagraph.block.item() - metagraph.last_update[uid].item())),
                str( metagraph.active[uid].item() ), 
                ep.ip + ':' + str(ep.port) if ep.is_serving else '[yellow]none[/yellow]', 
                ep.hotkey[:10],
                ep.coldkey[:10]
            ]
            total_stake += metagraph.stake[uid]
            total_rank += metagraph.ranks[uid]
            total_trust += metagraph.trust[uid]
            total_consensus += metagraph.consensus[uid]
            total_incentive += metagraph.incentive[uid]
            total_dividends += metagraph.dividends[uid]
            total_emission += int(metagraph.emission[uid] * 1000000000)
            TABLE_DATA.append(row)
        total_neurons = len(metagraph.uids)                
        table = Table(show_footer=False)
        table.title = (
            "[white]Metagraph: name: {}, block: {}, N: {}/{}, tau: {}/block, stake: {}, issuance: {}, difficulty: {}".format(subtensor.network, metagraph.block.item(), sum(metagraph.active.tolist()), metagraph.n.item(), bittensor.Balance.from_tao(metagraph.tau.item()), bittensor.Balance.from_tao(total_stake), issuance, difficulty )
        )
        table.add_column("[overline white]UID",  str(total_neurons), footer_style = "overline white", style='yellow')
        table.add_column("[overline white]STAKE(\u03C4)", '\u03C4{:.5f}'.format(total_stake), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]RANK", '{:.5f}'.format(total_rank), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]TRUST", '{:.5f}'.format(total_trust), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]CONSENSUS", '{:.5f}'.format(total_consensus), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]INCENTIVE", '{:.5f}'.format(total_incentive), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]DIVIDENDS", '{:.5f}'.format(total_dividends), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]EMISSION(\u03C1)", '\u03C1{}'.format(int(total_emission)), footer_style = "overline white", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]UPDATED", justify='right', no_wrap=True)
        table.add_column("[overline white]ACTIVE", justify='right', style='green', no_wrap=True)
        table.add_column("[overline white]AXON", justify='left', style='dim blue', no_wrap=True) 
        table.add_column("[overline white]HOTKEY", style='dim blue', no_wrap=False)
        table.add_column("[overline white]COLDKEY", style='dim purple', no_wrap=False)
        table.show_footer = True

        for row in TABLE_DATA:
            table.add_row(*row)
        table.box = None
        table.pad_edge = False
        table.width = None
        console.print(table)