Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs #77

Merged
merged 20 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.miner.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MINER_HF_ACCESS_TOKEN='REPLACE_WITH_HUGGINGFACE_ACCESS_KEY'
8 changes: 4 additions & 4 deletions .env.template → .env.validator.template
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Copy the contents on this file to a new file called .env
WANDB_API_KEY='REPLACE_WITH_WANDB_API_KEY'
MINER_HF_ACCESS_TOKEN='REPLACE_WITH_HUGGINGFACE_ACCESS_KEY'

HF_ACCESS_TOKEN='REPLACE_WITH_HUGGINGFACE_ACCESS_KEY'
HF_COLLECTION_SLUG='REPLACE_WITH_HUGGINGFACE_COLLECTION_SLUG'

# Git credentials
GIT_TOKEN='REPLACE_WITH_GIT_TOKEN'
GIT_USERNAME='REPLACE_WITH_GIT_USERNAME'
GIT_NAME="REPLACE_WITH_GIT_NAME"
GIT_EMAIL="REPLACE_WITH_GIT_EMAIL"
GIT_NAME='REPLACE_WITH_GIT_NAME'
GIT_EMAIL='REPLACE_WITH_GIT_EMAIL'
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ netuid = $(localnet_netuid)
network = $(localnet)
logging_level = debug # options= ['info', 'debug', 'trace']


################################################################################
# Network Parameters #
################################################################################
Expand Down Expand Up @@ -44,6 +43,7 @@ validator:
--netuid $(netuid) \
--logging.$(logging_level)


miner:
pm2 start python --name miner -- ./snp_oracle/neurons/miner.py \
--wallet.name $(coldkey) \
Expand All @@ -54,5 +54,5 @@ miner:
--logging.$(logging_level) \
--vpermit_tao_limit 2 \
--blacklist.force_validator_permit true \
--hf_repo_id foundryservices/mining_models \
--hf_repo_id your_repo_id \
--model mining_models/base_lstm_new.h5
7 changes: 7 additions & 0 deletions docs/Release Notes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Release Notes
=============

3.0.1
-----
Released on January 12 2025
- Improvements in validator README instructions
- Add flags to opt into additional functionality


3.0.0
-----
Released on January 10th 2025
Expand Down
4 changes: 2 additions & 2 deletions docs/miners.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ poetry install
## Configuration

#### Environment Variables
First copy the `.env.template` file to `.env`
First copy the `.env.miner.template` file to `.env`

```shell
cp .env.template .env
cp .env.miner.template .env
```

Update the `.env` file with your miner's values for the following properties.
Expand Down
30 changes: 23 additions & 7 deletions docs/validators.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,25 @@ poetry install
## Configuration

#### Environment Variables
First copy the `.env.template` file to `.env`
First copy the `.env.validator.template` file to `.env`

```shell
cp .env.template .env
cp .env.validator.template .env
```

Update the `.env` file with your validator's values.

```text
WANDB_API_KEY='REPLACE_WITH_WANDB_API_KEY'

HF_ACCESS_TOKEN='REPLACE_WITH_HUGGINGFACE_ACCESS_KEY'
HF_COLLECTION_SLUG='REPLACE_WITH_HUGGINGFACE_COLLECTION_SLUG'

(Optional - See Miner Data Upload to Hugging Face section)
GIT_TOKEN='REPLACE_WITH_GIT_TOKEN'
GIT_USERNAME='REPLACE_WITH_GIT_USERNAME'
GIT_NAME="REPLACE_WITH_GIT_NAME"
GIT_EMAIL="REPLACE_WITH_GIT_EMAIL"
GIT_NAME='REPLACE_WITH_GIT_NAME'
GIT_EMAIL='REPLACE_WITH_GIT_EMAIL'
```

See WandB API Key and HuggingFace setup below.
Expand All @@ -76,10 +80,22 @@ Before starting the process, validators would be required to procure a WANDB API
- Finally, run `wandb login` and paste your API key. Now you're all set with weights & biases.

#### HuggingFace Access Token
A huggingface access token can be procured from the huggingface platform. Follow the <a href='https://huggingface.co/docs/hub/en/security-tokens'>steps mentioned here</a> to get your huggingface access token.
A huggingface access token can be procured from the huggingface platform. Follow the <a href='https://huggingface.co/docs/hub/en/security-tokens'>steps mentioned here</a> to get your huggingface access token and add it to the ```HF_ACCESS_TOKEN``` environment variable. Ensure that your access token has all repository permissions and collection permissions checked.

#### HuggingFace Collection Slug
A Hugging Face collection is where the references to miner models will be stored. In order to create one, follow the <a href='https://huggingface.co/docs/hub/en/collections'>steps mentioned here</a>.

Once you have created a collection, copy and paste the <a href='https://huggingface.co/docs/huggingface_hub/main/en/guides/collections#fetch-a-collection'>collection slug</a> into the ```HF_COLLECTION_SLUG``` environment variable.

#### (Optional) Miner Data Upload to Hugging Face
Optionally, validators can choose to upload miner data at the end of each day to Hugging Face. The goal of this is to increase the transparency of our subnet. In order to participate, validators will need to create a <a href='https://huggingface.co/docs/hub/en/organizations'>Hugging Face organization</a>.

Once you have created an organization, pass the organization namespace into the ```--neuron.organization``` argument in the Makefile with your organizations namespace.

To turn on this feature, you will also need to add the ```--neuron.data_upload_on``` argument to the Makefile and set it to ```True```.

#### Git Access Token
A git token can be procured from the huggingface platform. Follow the <a href='https://huggingface.co/docs/hub/en/security-tokens'>steps mentioned here</a> to get your huggingface access token. Be sure to scope this token to the organization repository. The `username`, `name`, and `email` environment variable properties are all tied to your HuggingFace account.
#### (Optional) Git Access Token
A git token can be procured from the huggingface platform. Follow the <a href='https://huggingface.co/docs/hub/en/security-tokens'>steps mentioned here</a> to get your huggingface access token. Be sure to scope this token to the organization repository set with the argument above. The `GIT_TOKEN`, `GIT_USERNAME`, `GIT_EMAIL` and `GIT_NAME` environment variable properties are all tied to your HuggingFace account.

## Deploying a Validator
**IMPORTANT**
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "snp_oracle"
version = "3.0.0"
version = "3.0.1"
description = ""
authors = ["Foundry Digital"]
readme = "README.md"
Expand Down
1 change: 1 addition & 0 deletions snp_oracle/neurons/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def __init__(self, config=None):

wandb.init(
project=f"sn{self.config.netuid}-validators",
mode="disabled" if not getattr(self.config.neuron, "wandb_on", False) else "online",
entity="foundryservices",
config={
"hotkey": self.wallet.hotkey.ss58_address,
Expand Down
11 changes: 10 additions & 1 deletion snp_oracle/predictionnet/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,16 @@ def add_args(cls, parser):
"--neuron.organization",
type=str,
help="HuggingFace organization name for dataset storage",
default="foundryservices",
default="your_hugging_face_org",
)

parser.add_argument("--neuron.wandb_on", type=bool, help="Boolean toggle for wandb integration", default=False)

parser.add_argument(
"--neuron.data_upload_on",
type=bool,
help="Boolean toggle for validator HuggingFace data upload",
default=False,
)

# MINER ONLY CONFIG
Expand Down
84 changes: 51 additions & 33 deletions snp_oracle/predictionnet/validator/forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,27 @@ def can_process_data(response) -> bool:
return all([bool(response.repo_id), bool(response.data), bool(response.decryption_key), bool(response.prediction)])


async def process_miner_data(response, timestamp: str, organization: str, hotkey: str, uid: int) -> bool:
async def process_miner_data(
response, timestamp: str, organization: str, hotkey: str, uid: int, data_upload_on: bool = False
) -> bool:
"""
Verify that miner's data can be decrypted and attempt to store it.

Verify that miner's data can be decrypted and attempt to store it.
Args:
response: Response from miner containing encrypted data
timestamp: Current timestamp
organization: Organization name for HuggingFace
hotkey: Miner's hotkey for data organization
uid: Miner's UID

Returns:
bool: True if data was successfully decrypted, False otherwise
"""
try:
bt.logging.info(f"Processing data from UID {uid}...")

if not data_upload_on:
bt.logging.info(f"Data upload disabled, skipping storage for UID {uid}")
return True # Return True since this isn't a failure case

dataset_manager = DatasetManager(organization=organization)
data_path = f"{response.repo_id}/{response.data}"

Expand Down Expand Up @@ -72,9 +77,13 @@ async def process_miner_data(response, timestamp: str, organization: str, hotkey
return False


async def handle_market_close(self, dataset_manager: DatasetManager) -> None:
async def handle_market_close(self, dataset_manager: DatasetManager, data_upload_on: bool) -> None:
"""Handle data management operations when market is closed."""
try:
if not data_upload_on:
bt.logging.info("Data upload disabled, skipping market close operations")
return

# Clean up old data
dataset_manager.cleanup_local_storage(days_to_keep=2)

Expand All @@ -92,6 +101,22 @@ async def handle_market_close(self, dataset_manager: DatasetManager) -> None:
bt.logging.error(f"Error during market close operations: {str(e)}")


def log_to_wandb(wandb_on, miner_uids, responses, rewards, decryption_success):
if wandb_on:
# Log results to wandb
wandb_val_log = {
"miners_info": {
miner_uid: {
"miner_response": response.prediction,
"miner_reward": reward,
"decryption_success": success,
}
for miner_uid, response, reward, success in zip(miner_uids, responses, rewards, decryption_success)
}
}
wandb.log(wandb_val_log)


async def forward(self):
"""
The forward function is called by the validator every time step.
Expand All @@ -100,33 +125,31 @@ async def forward(self):
"""
ny_timezone = timezone("America/New_York")
current_time_ny = datetime.now(ny_timezone)
dataset_manager = DatasetManager(organization=self.config.neuron.organization)
daily_ops_done = False
dataset_manager = None
data_upload_on = getattr(self.config.neuron, "data_upload_on", False)

if data_upload_on:
dataset_manager = DatasetManager(organization=self.config.neuron.organization)

while True:
if await self.is_valid_time():
bt.logging.info("Market is open. Begin processes requests")
daily_ops_done = False # Reset flag when market opens
break

if not daily_ops_done:
await handle_market_close(self, dataset_manager)
else:
bt.logging.info("Market is closed. Sleeping for 2 minutes...")
time.sleep(120) # Sleep for 5 minutes before checking again
if datetime.now(ny_timezone) - current_time_ny >= timedelta(hours=1):
self.resync_metagraph()
self.set_weights()
self.past_predictions = [full((self.N_TIMEPOINTS, self.N_TIMEPOINTS), nan)] * len(self.hotkeys)
current_time_ny = datetime.now(ny_timezone)

if not daily_ops_done and data_upload_on and dataset_manager:
await handle_market_close(self, dataset_manager, data_upload_on)
daily_ops_done = True

# Check metagraph every hour
if datetime.now(ny_timezone) - current_time_ny >= timedelta(hours=1):
self.resync_metagraph()
self.set_weights()
self.past_predictions = [full((self.N_TIMEPOINTS, self.N_TIMEPOINTS), nan)] * len(self.hotkeys)
current_time_ny = datetime.now(ny_timezone)

time.sleep(120) # Sleep for 2 minutes

if datetime.now(ny_timezone) - current_time_ny >= timedelta(hours=1):
self.resync_metagraph()
self.set_weights()
self.past_predictions = [full((self.N_TIMEPOINTS, self.N_TIMEPOINTS), nan)] * len(self.hotkeys)
current_time_ny = datetime.now(ny_timezone)

# Get available miner UIDs
miner_uids = []
for uid in range(len(self.metagraph.S)):
Expand Down Expand Up @@ -161,6 +184,7 @@ async def forward(self):
organization=self.config.neuron.organization,
hotkey=self.metagraph.hotkeys[uid],
uid=uid,
data_upload_on=data_upload_on,
)
decryption_tasks.append(task)
else:
Expand All @@ -173,16 +197,10 @@ async def forward(self):
rewards = get_rewards(self, responses=responses, miner_uids=miner_uids)

# Zero out rewards for failed decryption
rewards = [reward if success else 0 for reward, success in zip(rewards, decryption_success)]
# rewards = [reward if success else 0 for reward, success in zip(rewards, decryption_success)]

# Log results to wandb
wandb_val_log = {
"miners_info": {
miner_uid: {"miner_response": response.prediction, "miner_reward": reward, "decryption_success": success}
for miner_uid, response, reward, success in zip(miner_uids, responses, rewards, decryption_success)
}
}
wandb.log(wandb_val_log)
wandb_on = self.config.neuron.wandb_on
log_to_wandb(wandb_on, miner_uids, responses, rewards, decryption_success)

# Log scores and update
bt.logging.info(f"Scored responses: {rewards}")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ def setUp(self):
def test_package_version(self):
# Check that version is as expected
# Must update to increment package version successfully
self.assertEqual(__version__, "3.0.0")
self.assertEqual(__version__, "3.0.1")
Loading