synapse-alpha / mirror-neuron

Experiments on bittensor reward models to find exploits
BSD 2-Clause "Simplified" License
1 stars 0 forks source link

Add support for subtensor #9

Closed steffencruz closed 1 year ago

steffencruz commented 1 year ago

We would like to be able to track the weight updates and run longer simulations, which may not be possible without a functional subtensor layer.

steffencruz commented 1 year ago

@joeylegere also says might be a mock flag for this option too

steffencruz commented 1 year ago

It is true! subtensor._mock exists!

steffencruz commented 1 year ago

(env) 07:00:15 steffencruz mirror_neuron $ py
Python 3.9.1 (default, Dec 11 2020, 06:28:49) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.13.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from sources.neuron import neuron
   ...: import os
   ...: c = neuron.config()
   ...: c.wallet.reregister=False
   ...: c.wallet._mock=True
   ...: c.subtensor._mock=True
   ...: os.makedirs('./tests/mock_subtensor/bin/OSX/node-subtensor',exist_ok=True)
   ...: n = neuron(config=c)

axon:
  external_ip: null
  external_port: null
  ip: '[::]'
  max_workers: 10
  maximum_concurrent_rpcs: 400
  port: 8091
  priority:
    max_workers: 5
    maxsize: 10
config: null
gating:
  learning_rate: 0.01
  model_name: EleutherAI/gpt-neo-125m
  momentum: 0.9
  num_uids: 4096
logging:
  debug: false
  logging_dir: ~/.bittensor/miners
  record_log: false
  trace: false
netuid: 1
neuron:
  alpha: 0.01
  axon_off: false
  base_prompt: '

    You are designed to assist with a wide range of tasks, from answering simple questions
    to providing in-depth explanations and discussions on a wide range of topics.

    '
  checkpoint_url: null
  device: cpu
  dont_save_events: false
  epoch_length_override: -1
  events_retention_size: 2 GB
  full_path: /Users/steffencruz/.bittensor/miners/default/default/netuid1/core_prompting_validator
  inference_only: false
  inference_timeout: 10
  inference_topk: 10
  length_timeout_multiplier: 0.01
  max_history: 100000
  name: core_prompting_validator
  no_reward_model: false
  question_prompt: '

    Ask me a random question about anything. Make the question very domain specific.
    Do not include the answer in the question.

    '
  reward_model_name: Dahoas/gpt2-rm-static
  reward_path: /Users/steffencruz/.bittensor/reward_models
  training_timeout: 4
  training_topk: 10
strict: false
subtensor:
  _mock: true
  chain_endpoint: null
  network: finney
  register:
    cuda:
      TPB: 256
    num_processes: null
    output_in_place: true
    update_interval: 50000
    verbose: false
wallet:
  _mock: true
  hotkey: default
  name: default
  path: ~/.bittensor/wallets/
  reregister: false

MockSub ws_port: 55608
Starting subtensor process with command: ['./tests/mock_subtensor/bin/OSX/node-subtensor', '--chain', './tests/mock_subtensor/specs/local_raw.json', '--base-path', './tmp/mock_chain_db_83844', '--execution', 'native', '--ws-max-connections', '1000', '--no-mdns', '--rpc-cors', 'all', '--port', '28184', '--rpc-port', '31205', '--ws-port', '55608', '--validator', '--alice']
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/steffencruz/Desktop/py/bittensor/bittensor/bittensor/_subtensor/subtensor_mock.py:145 in  │
│ create_global_mock_process                                                                       │
│                                                                                                  │
│   142 │   │   │                                                                                  │
│   143 │   │   │   print ('Starting subtensor process with command: {}'.format(command_args))     │
│   144 │   │   │                                                                                  │
│ ❱ 145 │   │   │   _mock_subtensor_process = subprocess.Popen(                                    │
│   146 │   │   │   │   command_args,                                                              │
│   147 │   │   │   │   close_fds=True, shell=False, stdout=subprocess.PIPE, stderr=subprocess.P   │
│   148                                                                                            │
│                                                                                                  │
│ /Users/steffencruz/opt/miniconda3/lib/python3.9/subprocess.py:947 in __init__                    │
│                                                                                                  │
│    944 │   │   │   │   │   self.stderr = io.TextIOWrapper(self.stderr,                           │
│    945 │   │   │   │   │   │   │   encoding=encoding, errors=errors)                             │
│    946 │   │   │                                                                                 │
│ ❱  947 │   │   │   self._execute_child(args, executable, preexec_fn, close_fds,                  │
│    948 │   │   │   │   │   │   │   │   pass_fds, cwd, env,                                       │
│    949 │   │   │   │   │   │   │   │   startupinfo, creationflags, shell,                        │
│    950 │   │   │   │   │   │   │   │   p2cread, p2cwrite,                                        │
│                                                                                                  │
│ /Users/steffencruz/opt/miniconda3/lib/python3.9/subprocess.py:1819 in _execute_child             │
│                                                                                                  │
│   1816 │   │   │   │   │   │   err_filename = orig_executable                                    │
│   1817 │   │   │   │   │   if errno_num != 0:                                                    │
│   1818 │   │   │   │   │   │   err_msg = os.strerror(errno_num)                                  │
│ ❱ 1819 │   │   │   │   │   raise child_exception_type(errno_num, err_msg, err_filename)          │
│   1820 │   │   │   │   raise child_exception_type(err_msg)                                       │
│   1821                                                                                           │
│   1822                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
PermissionError: [Errno 13] Permission denied: './tests/mock_subtensor/bin/OSX/node-subtensor'

During handling of the above exception, another exception occurred:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ <ipython-input-1-ac92968087f6>:8 in <module>                                                     │
│                                                                                                  │
│ /Users/steffencruz/Desktop/py/bittensor/mirror_neuron/sources/neuron.py:132 in __init__          │
│                                                                                                  │
│   129 │   │   bt.logging( config = self.config, logging_dir = self.config.neuron.full_path )     │
│   130 │   │   print( self.config )                                                               │
│   131 │   │                                                                                      │
│ ❱ 132 │   │   self.subtensor = bt.subtensor ( config = self.config )                             │
│   133 │   │   self.device = torch.device( self.config.neuron.device )                            │
│   134 │   │   self.wallet = bt.wallet ( config = self.config )                                   │
│   135 │   │   self.metagraph = bt.metagraph( netuid = self.config.netuid, network = self.subte   │
│                                                                                                  │
│ /Users/steffencruz/Desktop/py/bittensor/bittensor/bittensor/_subtensor/__init__.py:72 in __new__ │
│                                                                                                  │
│    69 │   │   config.subtensor._mock = _mock if _mock != None else config.subtensor._mock        │
│    70 │   │   if config.subtensor._mock == True or network == 'mock' or config.subtensor.get('   │
│    71 │   │   │   config.subtensor._mock = True                                                  │
│ ❱  72 │   │   │   return subtensor_mock.mock_subtensor.mock()                                    │
│    73 │   │                                                                                      │
│    74 │   │   # Determine config.subtensor.chain_endpoint and config.subtensor.network config.   │
│    75 │   │   # If chain_endpoint is set, we override the network flag, otherwise, the chain_e   │
│                                                                                                  │
│ /Users/steffencruz/Desktop/py/bittensor/bittensor/bittensor/_subtensor/subtensor_mock.py:79 in   │
│ mock                                                                                             │
│                                                                                                  │
│    76 │   │   │   if os.path.exists(f'{bittensor.__mock_chain_db__}_{os.getpid()}'):             │
│    77 │   │   │   │   # Name mock chain db using pid to avoid conflicts while multiple process   │
│    78 │   │   │   │   os.system(f'rm -rf {bittensor.__mock_chain_db__}_{os.getpid()}')           │
│ ❱  79 │   │   │   _owned_mock_subtensor_process = cls.create_global_mock_process(os.getpid())    │
│    80 │   │   else:                                                                              │
│    81 │   │   │   _owned_mock_subtensor_process = None                                           │
│    82 │   │   │   print ('Mock subtensor already running.')                                      │
│                                                                                                  │
│ /Users/steffencruz/Desktop/py/bittensor/bittensor/bittensor/_subtensor/subtensor_mock.py:174 in  │
│ create_global_mock_process                                                                       │
│                                                                                                  │
│   171 │   │   │                                                                                  │
│   172 │   │   │   return _mock_subtensor_process                                                 │
│   173 │   │   except Exception as e:                                                             │
│ ❱ 174 │   │   │   raise RuntimeError( 'Failed to start mocked subtensor process: {}'.format(e)   │
│   175                                                                                            │
│   176                                                                                            │
│   177 class Mock_Subtensor(subtensor_impl.Subtensor):                                            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
RuntimeError: Failed to start mocked subtensor process: [Errno 13] Permission denied: './tests/mock_subtensor/bin/OSX/node-subtensor'
steffencruz commented 1 year ago

As discussed by eugene, mock subtensor spawns a local blockchain which will introduce substantial overhead. Better to just mock it up in a trivial way. The following subtensor methods must be mocked:

neuron.py

  1. subtensor.check_config( config ): this is no problem
  2. subtensor.network: can be replaced with a hard-coded network name such as 'finney'
  3. subtensor.get_delegated( self.wallet.coldkeypub.ss58_address ): We are not ready to introduce delegation and so this should be something which has length 0 such as an empty dict or list
  4. subtensor.serve_axon( self.config.netuid, self.axon ): We are not ready to serve axons in the simulation and so an empty method would suffice.
  5. subtensor.block: This can likely be a placeholder value without causing trouble
  6. subtensor.validator_epoch_length(self.config.netuid): This can be substituted for a config parameter
  7. subtensor.set_weights( ... ): Updates chain weights which we are also not ready for yet
  8. BONUS bittensor.utils.weight_utils.process_weights_for_netuid( ... ): parses the raw weights in the previous step and applies constraints. This will also only be relevant when 7 is running
steffencruz commented 1 year ago

Closed by #48