From 5929734149ad2d085537414d40093ef81c3fdc3f Mon Sep 17 00:00:00 2001 From: Dmytro Bobrenko <17252809+dbobrenko@users.noreply.github.com> Date: Mon, 11 Aug 2025 21:57:27 +0200 Subject: [PATCH 1/5] Aggregate all weight sync hotkeys --- apex/validator/miner_scorer.py | 5 ++++- apex/validator/weight_syncer.py | 5 ++++- tests/validator/test_weight_syncer.py | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apex/validator/miner_scorer.py b/apex/validator/miner_scorer.py index b24490cbb..a3985c8a6 100644 --- a/apex/validator/miner_scorer.py +++ b/apex/validator/miner_scorer.py @@ -125,7 +125,10 @@ async def set_scores(self) -> bool: if hkey_agg_rewards: rewards_array = np.array(list(hkey_agg_rewards.values())) - logger.debug(f"Setting weights, reward mean={rewards_array.mean():.4f} min={rewards_array.min():.4f}") + logger.debug( + f"Setting weights to {len(hkey_agg_rewards)} hotkeys; " + f"reward mean={rewards_array.mean():.4f} min={rewards_array.min():.4f}" + ) else: logger.warning(f"Setting empty rewards: {hkey_agg_rewards}") diff --git a/apex/validator/weight_syncer.py b/apex/validator/weight_syncer.py index 5327e335f..666aa7c98 100644 --- a/apex/validator/weight_syncer.py +++ b/apex/validator/weight_syncer.py @@ -150,13 +150,16 @@ async def compute_weighted_rewards(self, hotkey_rewards: dict[str, float]) -> di results = await asyncio.gather(*validator_rewards_tasks.values(), return_exceptions=True) + all_miner_hotkeys: set[str] = set() validator_rewards: dict[int, dict[str, float]] = {} for uid, result in zip(validator_rewards_tasks, results, strict=True): if isinstance(result, BaseException) or not result: logger.warning(f"Cannot receive rewards from uid {uid}: {result}") continue validator_rewards[uid] = result + all_miner_hotkeys.update(result) logger.debug(f"Received rewards from validator {uid} with stake {metagraph.stake[uid]}") + logger.debug(f"Total amount of unique hotkeys from all validators: {len(all_miner_hotkeys)}") all_validator_uids = [own_uid] + list(validator_rewards.keys()) total_stake = sum(metagraph.stake[uid] for uid in all_validator_uids) @@ -168,7 +171,7 @@ async def compute_weighted_rewards(self, hotkey_rewards: dict[str, float]) -> di own_stake = metagraph.stake[own_uid] weighted_rewards: dict[str, float] = {} - for miner_hkey in hotkey_rewards: + for miner_hkey in all_miner_hotkeys: own_reward = hotkey_rewards.get(miner_hkey, 0.0) total_weighted_reward = own_reward * own_stake diff --git a/tests/validator/test_weight_syncer.py b/tests/validator/test_weight_syncer.py index 26355565b..17a0030b6 100644 --- a/tests/validator/test_weight_syncer.py +++ b/tests/validator/test_weight_syncer.py @@ -78,11 +78,12 @@ async def test_compute_weighted_rewards_happy_path(weight_syncer, mock_metagraph # self (1000) + validator1 (2000) = 3000 total stake # miner1: (0.9 * 1000 + 0.85 * 2000) / 3000 = 0.8666 # miner2: (0.1 * 1000 + 0.82 * 2000) / 3000 = 0.58 + # miner3: (0.0 * 1000 + 0.70 * 2000) / 3000 = 0.4666 assert mock_receive.call_count == 1 assert mock_receive.call_args.args[1] == 1 # Called for UID 1 assert pytest.approx(weighted_rewards["miner1"], 0.001) == 0.8666 assert pytest.approx(weighted_rewards["miner2"], 0.001) == 0.58 - assert "miner3" not in weighted_rewards + assert pytest.approx(weighted_rewards["miner3"], 0.001) == 0.4666 @pytest.mark.asyncio From c238ee358eba998ee4ad7970614a6dfe2ea3b1e3 Mon Sep 17 00:00:00 2001 From: Dmytro Bobrenko <17252809+dbobrenko@users.noreply.github.com> Date: Mon, 11 Aug 2025 22:07:46 +0200 Subject: [PATCH 2/5] Range all uids for weight set --- apex/common/async_chain.py | 2 +- tests/common/mock_async_chain.py | 1 + tests/common/test_async_chain.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apex/common/async_chain.py b/apex/common/async_chain.py index d4e8a2a61..fa3815144 100644 --- a/apex/common/async_chain.py +++ b/apex/common/async_chain.py @@ -114,7 +114,7 @@ async def set_weights(self, rewards: dict[str, float]) -> bool: try: metagraph = await self.metagraph() subtensor = await self.subtensor() - weights: dict[int, float] = {} + weights: dict[int, float] = dict.fromkeys(range(int(metagraph.n)), 0.0) for hotkey, reward in rewards.items(): try: diff --git a/tests/common/mock_async_chain.py b/tests/common/mock_async_chain.py index 1c0312fdd..ec9132e89 100644 --- a/tests/common/mock_async_chain.py +++ b/tests/common/mock_async_chain.py @@ -13,6 +13,7 @@ class DummyMetagraph: def __init__(self, hotkeys: Iterable[str] | None = None, uids: Iterable[int] | None = None) -> None: self.hotkeys = list(hotkeys or ()) self.uids = list(uids or ()) + self.n = 2 class DummySubtensor: diff --git a/tests/common/test_async_chain.py b/tests/common/test_async_chain.py index 85092880c..cafdd984e 100644 --- a/tests/common/test_async_chain.py +++ b/tests/common/test_async_chain.py @@ -120,8 +120,8 @@ async def test_set_weights_happy_path(monkeypatch): assert ok is True assert stub.last_set_weights is not None - assert stub.last_set_weights["uids"] == [2] - assert stub.last_set_weights["weights"] == [0.7] + assert stub.last_set_weights["uids"] == [0, 1, 2] + assert stub.last_set_weights["weights"] == [0.0, 0.0, 0.7] assert stub.last_set_weights["version_key"] == __spec_version__ From bf8023ff6a4c1b70a058417f3eebcb62d12d0c1c Mon Sep 17 00:00:00 2001 From: Dmytro Bobrenko <17252809+dbobrenko@users.noreply.github.com> Date: Mon, 11 Aug 2025 22:08:35 +0200 Subject: [PATCH 3/5] Simplify mock metagraph --- tests/common/mock_async_chain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/mock_async_chain.py b/tests/common/mock_async_chain.py index ec9132e89..10f6be35c 100644 --- a/tests/common/mock_async_chain.py +++ b/tests/common/mock_async_chain.py @@ -13,7 +13,7 @@ class DummyMetagraph: def __init__(self, hotkeys: Iterable[str] | None = None, uids: Iterable[int] | None = None) -> None: self.hotkeys = list(hotkeys or ()) self.uids = list(uids or ()) - self.n = 2 + self.n = len(self.uids) class DummySubtensor: From 72db67066009f739be6074ebf0ce8dd07c3e830f Mon Sep 17 00:00:00 2001 From: Dmytro Bobrenko <17252809+dbobrenko@users.noreply.github.com> Date: Tue, 12 Aug 2025 11:06:33 +0200 Subject: [PATCH 4/5] Add more logs, lower validator stake --- apex/validator/pipeline.py | 1 + apex/validator/weight_syncer.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apex/validator/pipeline.py b/apex/validator/pipeline.py index a87b9cf28..41079a985 100644 --- a/apex/validator/pipeline.py +++ b/apex/validator/pipeline.py @@ -100,6 +100,7 @@ async def run_single(self, task: QueryTask) -> str: except BaseException as exc: logger.warning(f"Failed to generate redundant reference: {exc}") + logger.debug(f"Querying discriminators with reference GT: {ground_truth}, query: {query[:20]}..") discriminator_results = await self.miner_registry.query_discriminators( query=query, generator_results=generator_results, reference=reference, ground_truth=ground_truth ) diff --git a/apex/validator/weight_syncer.py b/apex/validator/weight_syncer.py index 666aa7c98..a4bf55f00 100644 --- a/apex/validator/weight_syncer.py +++ b/apex/validator/weight_syncer.py @@ -30,7 +30,7 @@ class WeightSyncer: def __init__( self, chain: AsyncChain, - min_alpha_stake: float = 100_000, + min_alpha_stake: float = 15_000, verified_hotkeys: dict[str, str | None] | None = None, enable_receive: bool = True, enable_send: bool = True, From 89652377d5518d8b2d712be77030c3abf92f134f Mon Sep 17 00:00:00 2001 From: Dmytro Bobrenko <17252809+dbobrenko@users.noreply.github.com> Date: Tue, 12 Aug 2025 11:31:29 +0200 Subject: [PATCH 5/5] Remove redundant logs --- apex/validator/miner_sampler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apex/validator/miner_sampler.py b/apex/validator/miner_sampler.py index 1a34ea099..c4fc10433 100644 --- a/apex/validator/miner_sampler.py +++ b/apex/validator/miner_sampler.py @@ -163,7 +163,6 @@ async def query_generators(self, query: str) -> MinerGeneratorResults: hotkeys: list[str] = [] tasks: list[Coroutine[str, str, Any]] = [] - logger.debug(f"Querying {len(miner_information)} miner generators") for miner_info in miner_information: hotkeys.append(miner_info.hotkey) tasks.append(self.query_miners(body=body, endpoint=miner_info.address, hotkey=miner_info.hotkey))