Skip to content

Commit 2160b79

Browse files
authored
Merge pull request #141 from web-genie-ai/feat/vtrust-issue
Feat/vtrust issue
2 parents cbff857 + cf88bd7 commit 2160b79

File tree

7 files changed

+192
-58
lines changed

7 files changed

+192
-58
lines changed

neurons/validators/genie_validator.py

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import bittensor as bt
33
import numpy as np
44
import random
5+
import requests
56
import threading
67
import time
78

@@ -27,6 +28,9 @@
2728
SeoChallenge,
2829
BalancedChallenge,
2930
)
31+
from webgenie.datasets.central_dataset import (
32+
CentralDataset,
33+
)
3034
from webgenie.helpers.htmls import preprocess_html, is_valid_resources
3135
from webgenie.helpers.images import image_debug_str
3236
from webgenie.helpers.llms import set_seed
@@ -45,7 +49,6 @@
4549
from webgenie.tasks.image_task_generator import ImageTaskGenerator
4650
from webgenie.utils.uids import get_all_available_uids
4751

48-
4952
class GenieValidator:
5053
def __init__(self, neuron: BaseNeuron):
5154
self.neuron = neuron
@@ -57,6 +60,17 @@ def __init__(self, neuron: BaseNeuron):
5760
self.task_generators = [
5861
(ImageTaskGenerator(), 1.0), # currently only image task generator is supported
5962
]
63+
self.init_signature()
64+
65+
def init_signature(self):
66+
"""Get signature for central database authentication using wallet"""
67+
try:
68+
message = b"I am the owner of the wallet"
69+
CentralDataset.SIGNATURE = self.neuron.wallet.hotkey.sign(message).hex()
70+
CentralDataset.HOTKEY = self.neuron.wallet.hotkey.ss58_address
71+
except Exception as e:
72+
bt.logging.error(f"Error initializing signature: {e}")
73+
raise e
6074

6175
async def query_miners(self):
6276
try:
@@ -82,8 +96,8 @@ async def query_miners(self):
8296
available_challenges_classes = [
8397
AccuracyChallenge,
8498
SeoChallenge,
99+
AccuracyChallenge,
85100
SeoChallenge,
86-
BalancedChallenge,
87101
]
88102

89103
with self.lock:
@@ -249,7 +263,7 @@ async def score(self):
249263
except Exception as e:
250264
bt.logging.error(f"Error storing results to database: {e}")
251265

252-
async def synthensize_task(self):
266+
async def synthensize_task(self, session:int, task_number:int):
253267
try:
254268
with self.lock:
255269
if len(self.synthetic_tasks) > MAX_SYNTHETIC_TASK_SIZE:
@@ -263,23 +277,43 @@ async def synthensize_task(self):
263277
weights=[weight for _, weight in self.task_generators],
264278
)[0]
265279

266-
task, synapse = await task_generator.generate_task()
280+
task, synapse = await task_generator.generate_task(session, task_number)
267281
with self.lock:
268282
self.synthetic_tasks.append((task, synapse))
269283

270284
bt.logging.success(f"Successfully generated task for {task.src}")
271-
272285
except Exception as e:
273286
bt.logging.error(f"Error in synthensize_task: {e}")
274287
raise e
275288

276289
def get_seed(self, session: int, task_index: int, hash_cache: dict = {}) -> int:
277-
if session not in hash_cache:
278-
session_start_block = session * SESSION_WINDOW_BLOCKS
279-
subtensor = self.neuron.subtensor
280-
block_hash = subtensor.get_block_hash(session_start_block)
281-
hash_cache[session] = int(block_hash[-15:], 16)
282-
return int(hash_cache[session] + task_index)
290+
try:
291+
method = "GET"
292+
url = "http://209.126.9.130:18000/api/v1/task/seed"
293+
response = requests.request(method, url, params={"session": session, "task_number": task_index})
294+
if response.status_code == 200:
295+
response_json = response.json()
296+
success = response_json["success"]
297+
if not success:
298+
raise Exception(f"Failed to get seed from API: {seed}")
299+
300+
seed = response_json["seed"], response_json["task_id_seed"]
301+
302+
if seed is None:
303+
raise Exception(f"Seed is None")
304+
return seed
305+
else:
306+
raise Exception(f"Failed to get seed from API: {response.status_code}")
307+
308+
except Exception as e:
309+
raise e
310+
311+
# if session not in hash_cache:
312+
# session_start_block = session * SESSION_WINDOW_BLOCKS
313+
# subtensor = self.neuron.subtensor
314+
# block_hash = subtensor.get_block_hash(session_start_block)
315+
# hash_cache[session] = int(block_hash[-15:], 16)
316+
# return int(hash_cache[session] + task_index)
283317

284318
async def forward(self):
285319
try:
@@ -290,25 +324,30 @@ async def forward(self):
290324
else:
291325
task_index = self.neuron.score_manager.number_of_tasks
292326

327+
session = int(session)
328+
task_index = int(task_index)
329+
293330
if task_index >= MAX_NUMBER_OF_TASKS_PER_SESSION:
294331
return
295332

333+
296334
bt.logging.info(f"Forwarding task #{task_index} in session #{session}")
297-
seed = self.get_seed(session, task_index)
335+
#seed, task_id_seed = self.get_seed(session, task_index)
298336

299-
bt.logging.info(f"Init random with seed: {seed}")
300-
random.seed(seed)
301-
set_seed(seed)
337+
#bt.logging.info(f"Random seed: {seed} | task_id_seed: {task_id_seed}")
338+
#random.seed(seed)
339+
#set_seed(seed)
302340

303-
while True:
304-
try:
305-
await self.synthensize_task()
306-
break
307-
except Exception as e:
308-
bt.logging.error(
309-
f"Error in synthensize_task: {e}"
310-
f"Retrying..."
311-
)
341+
try:
342+
await self.synthensize_task(session, task_index)
343+
task, synapse = self.synthetic_tasks[-1]
344+
task.task_id = f"{session}_{task_index}"
345+
synapse.task_id = task.task_id
346+
except Exception as e:
347+
bt.logging.error(
348+
f"Error in synthensize_task: {e}"
349+
)
350+
return
312351

313352
await self.query_miners()
314353
await self.score()

neurons/validators/score_manager.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -183,38 +183,38 @@ def get_winner(self, total_scores: np.ndarray, solved_tasks: np.ndarray, number_
183183
return winner
184184

185185
def get_scores(self, session_upto: int):
186-
scores = np.zeros(self.neuron.metagraph.n, dtype=np.float32)
187-
for session_number in self.session_results:
188-
if (session_number <= session_upto - CONSIDERING_SESSION_COUNTS or
189-
session_number > session_upto):
190-
continue
191-
192-
try:
193-
winner = self.session_results[session_number]["winner"]
194-
competition_type = self.session_results[session_number]["competition_type"]
195-
if winner == -1:
196-
continue
197-
scores[winner] += RESERVED_WEIGHTS[competition_type]
198-
except Exception as e:
199-
bt.logging.warning(f"Error getting scores: {e}")
200-
201-
return scores
202186
# scores = np.zeros(self.neuron.metagraph.n, dtype=np.float32)
203-
# tiny_weight = 1 / 128
204-
# big_weight = 1.0
205187
# for session_number in self.session_results:
206188
# if (session_number <= session_upto - CONSIDERING_SESSION_COUNTS or
207189
# session_number > session_upto):
208190
# continue
209-
210-
# winner = self.session_results[session_number]["winner"]
211-
# if winner == -1:
212-
# continue
213-
# if session_number == session_upto:
214-
# scores[winner] += big_weight
215-
# else:
216-
# scores[winner] += tiny_weight
191+
192+
# try:
193+
# winner = self.session_results[session_number]["winner"]
194+
# competition_type = self.session_results[session_number]["competition_type"]
195+
# if winner == -1:
196+
# continue
197+
# scores[winner] += RESERVED_WEIGHTS[competition_type]
198+
# except Exception as e:
199+
# bt.logging.warning(f"Error getting scores: {e}")
200+
217201
# return scores
202+
scores = np.zeros(self.neuron.metagraph.n, dtype=np.float32)
203+
tiny_weight = 1 / 128
204+
big_weight = 1.0
205+
for session_number in self.session_results:
206+
if (session_number <= session_upto - CONSIDERING_SESSION_COUNTS or
207+
session_number > session_upto):
208+
continue
209+
210+
winner = self.session_results[session_number]["winner"]
211+
if winner == -1:
212+
continue
213+
if session_number == session_upto:
214+
scores[winner] += big_weight
215+
else:
216+
scores[winner] += tiny_weight
217+
return scores
218218

219219
# if session_upto in self.session_results:
220220
# scores = self.session_results[session_upto]["scores"]

tests/test_llms.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import os
3+
import random
34

45
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
56
sys.path.append(parent_dir)
@@ -10,7 +11,7 @@
1011
import asyncio
1112
from pydantic import BaseModel
1213

13-
from webgenie.helpers.llms import openai_call
14+
from webgenie.helpers.llms import openai_call, set_seed
1415

1516

1617
class HTML(BaseModel):
@@ -20,15 +21,16 @@ class HTML(BaseModel):
2021
async def test_openai_call():
2122
result = await openai_call(
2223
messages = [
23-
{"role": "system", "content": "You are an expert web developer who specializes in HTML and CSS. A user will provide you with the webpage requirements. You need to return a single html file that uses HTML and CSS to satisfy the requirements. Include all CSS code in the HTML file itself. If it involves any images, use 'rick.jpg' as the placeholder. Do not hallucinate any dependencies to external files. You do not need to include JavaScript scripts for dynamic interactions. Pay attention to things like size, text, position, and color of all the elements, as well as the overall layout. Respond with the content of the HTML+CSS file:"},
24-
{"role": "user", "content": "Create a webpage with a red background and a blue rectangle in the center."},
24+
{"role": "system", "content": "Could you make the following webpage more complex? It should be more complex and have more elements."},
25+
{"role": "user", "content": """<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>Red Background with Blue Rectangle</title>\n <style>\n body {\n margin: 0;\n height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: red;\n }\n .blue-rectangle {\n width: 300px;\n height: 200px;\n background-color: blue;\n }\n </style>\n</head>\n<body>\n <div class="blue-rectangle"></div>\n</body>\n</html>"""},
2526
],
2627
response_format = HTML,
2728
)
2829
print(result)
2930

3031

3132
if __name__ == "__main__":
33+
set_seed(5)
3234
asyncio.run(test_openai_call())
3335

3436

webgenie/challenges/challenge.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async def calculate_scores(self) -> dict[str, np.ndarray]:
4343
scores = await self.task.generator.calculate_scores(self.task, self.solutions)
4444
accuracy_scores = scores[ACCURACY_METRIC_NAME]
4545
seo_scores = scores[SEO_METRIC_NAME]
46-
aggregated_scores = np.where(accuracy_scores > 0.7, seo_scores, 0)
46+
aggregated_scores = np.where(accuracy_scores > 0.9, seo_scores, 0)
4747
return aggregated_scores, scores
4848

4949

@@ -54,7 +54,7 @@ async def calculate_scores(self) -> dict[str, np.ndarray]:
5454
scores = await self.task.generator.calculate_scores(self.task, self.solutions)
5555
accuracy_scores = scores[ACCURACY_METRIC_NAME]
5656
quality_scores = scores[QUALITY_METRIC_NAME]
57-
aggregated_scores = np.where(accuracy_scores > 0.7, quality_scores, 0)
57+
aggregated_scores = np.where(accuracy_scores > 0.9, quality_scores, 0)
5858
return aggregated_scores, scores
5959

6060

webgenie/datasets/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .dataset import Dataset, DatasetEntry
22
from .synthetic_dataset import SyntheticDataset
33
from .huggingface_dataset import HuggingfaceDataset
4-
from .random_website_dataset import RandomWebsiteDataset
4+
from .random_website_dataset import RandomWebsiteDataset
5+
from .central_dataset import CentralDataset
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# https://huggingface.co/datasets/SALT-NLP/Design2Code_human_eval_pairwise
2+
3+
import bittensor as bt
4+
import random
5+
import requests
6+
from datasets import load_dataset
7+
8+
from webgenie.datasets.dataset import Dataset, DatasetEntry
9+
10+
11+
class CentralDataset(Dataset):
12+
HOTKEY = "hotkey"
13+
SIGNATURE = "signature"
14+
15+
def __init__(self):
16+
pass
17+
18+
async def generate_context(self) -> DatasetEntry:
19+
pass
20+
21+
async def generate_context(self, session:int, task_number:int)->DatasetEntry:
22+
try:
23+
bt.logging.info("Generating Central context")
24+
html = self.get_html(session, task_number)
25+
return DatasetEntry(
26+
src="central",
27+
url=f"central_{session}_{task_number}",
28+
ground_truth_html=html,
29+
prompt="",
30+
base64_image=""
31+
)
32+
except Exception as e:
33+
bt.logging.error(f"Error in generate_context: {e}")
34+
raise e
35+
36+
def get_html(self, session:int, task_number:int)->str:
37+
bt.logging.info(f"Getting HTML for session {session} and task {task_number}")
38+
method = "GET"
39+
url = f"http://209.126.9.130:18000/api/v1/task/generate"
40+
headers = {
41+
"Signature": CentralDataset.SIGNATURE,
42+
"Hotkey": CentralDataset.HOTKEY
43+
}
44+
params = {
45+
"session": int(session),
46+
"task_number": int(task_number)
47+
}
48+
response = requests.request(method, url, headers=headers, params=params)
49+
50+
if response.status_code != 200:
51+
raise Exception(f"Failed to get HTML: {response.status_code} {response.text}")
52+
bt.logging.info(f"HTML: {response.json()}")
53+
return response.json()["html"]

0 commit comments

Comments
 (0)