diff --git a/.gitignore b/.gitignore index 5dfe5518..e05499bf 100644 --- a/.gitignore +++ b/.gitignore @@ -163,6 +163,9 @@ cython_debug/ #.idea/ testing/ +data/* +plots/* +notebooks/* core app.config.js wandb diff --git a/README.md b/README.md index f78fc33a..b2d83a76 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ git clone https://github.com/opentensor/prompting.git cd prompting bash install.sh ``` +If you are running a miner, you will also need to uninstall uvloop. +```bash +pip uninstall uvloop -y +``` @@ -70,9 +74,8 @@ python ``` where `SCRIPT_PATH` is either: -1. neurons/miners/huggingface/miner.py -2. neurons/miners/openai/miner.py -3. neurons/validator.py +1. neurons/miners/openai/miner.py +2. neurons/validator.py For ease of use, you can run the scripts as well with PM2. Installation of PM2 is: **On Linux**: @@ -80,12 +83,21 @@ For ease of use, you can run the scripts as well with PM2. Installation of PM2 i sudo apt update && sudo apt install jq && sudo apt install npm && sudo npm install pm2 -g && pm2 update ``` -Example of running a Llama3 miner: +Example of running an Openai miner on Main: ```bash -pm2 start neurons/miners/huggingface/miner.py --interpreter python3 --name llama3_miner -- --netuid 1 --subtensor.network finney --wallet.name my_wallet --wallet.hotkey m1 --neuron.model_id casperhansen/llama-3-70b-instruct-awq --neuron.load_in_4bit True --axon.port 21988 --logging.debug +pm2 start neurons/miners/openai/miner.py --interpreter python --name openai_miner -- --netuid 1 --subtensor.network finney --wallet.name my_wallet --wallet.hotkey my_hotkey --neuron.model_id gpt-3.5-turbo-1106 --axon.port 8091 ``` +## Running with autoupdate + +You can run the validator in auto-update mode by using pm2 along with the `run.sh` bash script. This command will initiate two pm2 processes: one for auto-update monitoring, named **s1_validator_update**, and another for running the validator itself, named **s1_validator_main_process**. +```bash +pm2 start run.sh --name s1_validator_autoupdate -- --wallet.name --wallet.hotkey +``` + +> Note: this is not an end solution, major releases or changes in requirements will still require you to manually restart the processes. Regularly monitor the health of your validator to ensure optimal performance. + # Testnet We highly recommend that you run your miners on testnet before deploying on main. This is give you an opportunity to debug your systems, and ensure that you will not lose valuable immunity time. The SN1 testnet is **netuid 61**. @@ -94,7 +106,7 @@ In order to run on testnet, you will need to go through the same hotkey registra To run: ```bash -pm2 start neurons/miners/huggingface/miner.py --interpreter python3 --name llama3_miner -- --netuid 61 --subtensor.network test --wallet.name my_test_wallet --wallet.hotkey m1 --neuron.model_id casperhansen/llama-3-70b-instruct-awq --neuron.load_in_4bit True --axon.port 21988 --logging.debug +pm2 start neurons/miners/openai/miner.py --interpreter python3 --name openai_miner -- --netuid 61 --subtensor.network test --wallet.name my_test_wallet --wallet.hotkey my_test_hotkey --neuron.model_id gpt-3.5-turbo-1106 --axon.port 8091 ``` # Limitations diff --git a/neurons/miners/huggingface/miner.py b/neurons/miners/huggingface/miner.py index 29eaa640..6c33730d 100644 --- a/neurons/miners/huggingface/miner.py +++ b/neurons/miners/huggingface/miner.py @@ -17,10 +17,11 @@ import time import bittensor as bt from prompting.miners import HuggingFaceMiner +from deprecated import deprecated -# This is the main function, which runs the miner. -if __name__ == "__main__": +@deprecated(version="2.4.1+", reason="Class is deprecated, use openai miner for reference on example miner.") +def main(): with HuggingFaceMiner() as miner: while True: miner.log_status() @@ -29,3 +30,7 @@ if miner.should_exit: bt.logging.warning("Ending miner...") break + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/prompting/__init__.py b/prompting/__init__.py index 65aed54e..1639249d 100644 --- a/prompting/__init__.py +++ b/prompting/__init__.py @@ -16,7 +16,7 @@ # DEALINGS IN THE SOFTWARE. # Define the version of the template module. -__version__ = "2.4.2" +__version__ = "2.5.2" version_split = __version__.split(".") __spec_version__ = ( (10000 * int(version_split[0])) diff --git a/prompting/base/miner.py b/prompting/base/miner.py index e23cbcbf..f0653abe 100644 --- a/prompting/base/miner.py +++ b/prompting/base/miner.py @@ -104,12 +104,12 @@ def run(self): self.axon.start() bt.logging.info(f"Miner starting at block: {self.block}") - + last_update_block = 0 # This loop maintains the miner's operations until intentionally stopped. try: while not self.should_exit: while ( - self.block - self.metagraph.last_update[self.uid] + self.block - last_update_block < self.config.neuron.epoch_length ): # Wait before checking again. @@ -121,6 +121,7 @@ def run(self): # Sync metagraph and potentially set weights. self.sync() + last_update_block = self.block self.step += 1 # If someone intentionally stops the miner, it'll safely terminate operations. diff --git a/prompting/base/prompting_miner.py b/prompting/base/prompting_miner.py index f6b18818..1668f96f 100644 --- a/prompting/base/prompting_miner.py +++ b/prompting/base/prompting_miner.py @@ -23,7 +23,7 @@ from prompting.protocol import StreamPromptingSynapse from prompting.base.miner import BaseStreamMinerNeuron from datetime import datetime - +from typing import List, Dict class BaseStreamPromptingMiner(BaseStreamMinerNeuron): """ @@ -159,27 +159,38 @@ def init_wandb(self): def log_event( self, + synapse: StreamPromptingSynapse, timing: float, - prompt: str, - completion: str, - system_prompt: str, + messages, + accumulated_chunks: List[str] = [], + accumulated_chunks_timings: List[float] = [], extra_info: dict = {}, ): if not getattr(self, "wandb_run", None): self.init_wandb() - + + dendrite_uid = self.metagraph.hotkeys.index(synapse.dendrite.hotkey) step_log = { "epoch_time": timing, - # "block": self.last_epoch_block, - "prompt": prompt, - "completion": completion, - "system_prompt": system_prompt, - "uid": self.metagraph.hotkeys.index(self.wallet.hotkey.ss58_address), - "stake": self.metagraph.S[self.uid].item(), - "trust": self.metagraph.T[self.uid].item(), - "incentive": self.metagraph.I[self.uid].item(), - "consensus": self.metagraph.C[self.uid].item(), - "dividends": self.metagraph.D[self.uid].item(), + # TODO: add block to logs in the future in a way that doesn't impact performance + # "block": self.block, + "messages": messages, + "accumulated_chunks": accumulated_chunks, + "accumulated_chunks_timings": accumulated_chunks_timings, + "validator_uid": dendrite_uid, + "validator_ip": synapse.dendrite.ip, + "validator_coldkey": self.metagraph.coldkeys[dendrite_uid], + "validator_hotkey": self.metagraph.hotkeys[dendrite_uid], + "validator_stake": self.metagraph.S[dendrite_uid].item(), + "validator_trust": self.metagraph.T[dendrite_uid].item(), + "validator_incentive": self.metagraph.I[dendrite_uid].item(), + "validator_consensus": self.metagraph.C[dendrite_uid].item(), + "validator_dividends": self.metagraph.D[dendrite_uid].item(), + "miner_stake": self.metagraph.S[self.uid].item(), + "miner_trust": self.metagraph.T[self.uid].item(), + "miner_incentive": self.metagraph.I[self.uid].item(), + "miner_consensus": self.metagraph.C[self.uid].item(), + "miner_dividends": self.metagraph.D[self.uid].item(), **extra_info, } diff --git a/prompting/forward.py b/prompting/forward.py index c6f0ad26..a3a63272 100644 --- a/prompting/forward.py +++ b/prompting/forward.py @@ -36,6 +36,8 @@ from prompting.utils.uids import get_random_uids from dataclasses import dataclass +SINGLE_TURN_TASKS = ['sentiment', 'translation'] + @async_log async def generate_reference(agent): loop = asyncio.get_running_loop() @@ -321,6 +323,9 @@ async def forward(self): if random.random()<0.5 or turn>=1: break + if task.name in SINGLE_TURN_TASKS: + break + history = '\n'.join([f"{role}: {message}" for role, message in zip(roles, messages)]) # Use PREVIOUS task context diff --git a/prompting/miners/__init__.py b/prompting/miners/__init__.py index 9c3a34bf..f53f9bb4 100644 --- a/prompting/miners/__init__.py +++ b/prompting/miners/__init__.py @@ -4,5 +4,4 @@ from .phrase import PhraseMiner # Real miners -from .hf_miner import HuggingFaceMiner -from .openai_miner import OpenAIMiner +from .openai_miner import OpenAIMiner \ No newline at end of file diff --git a/prompting/miners/hf_miner.py b/prompting/miners/hf_miner.py index 021361d9..659035fd 100644 --- a/prompting/miners/hf_miner.py +++ b/prompting/miners/hf_miner.py @@ -28,8 +28,9 @@ # import base miner class which takes care of most of the boilerplate from prompting.base.prompting_miner import BaseStreamPromptingMiner +from deprecated import deprecated - +@deprecated(version="2.4.1+", reason="Class is deprecated, use openai miner for reference on example miner.") class HuggingFaceMiner(BaseStreamPromptingMiner): """ Base miner which runs zephyr (https://huggingface.co/HuggingFaceH4/zephyr-7b-beta) diff --git a/prompting/miners/langchain_miner.py b/prompting/miners/langchain_miner.py new file mode 100644 index 00000000..b77d1433 --- /dev/null +++ b/prompting/miners/langchain_miner.py @@ -0,0 +1,169 @@ +# The MIT License (MIT) +# Copyright © 2024 Yuma Rao + +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +# documentation files (the “Software”), to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all copies or substantial portions of +# the Software. + +# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +# THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +import time +import os +import bittensor as bt +import argparse +from starlette.types import Send +from functools import partial +from typing import Dict, Awaitable + +# Bittensor Miner Template: +from prompting.base.prompting_miner import BaseStreamPromptingMiner +from prompting.protocol import StreamPromptingSynapse + +# import base miner class which takes care of most of the boilerplate + +from prompting.miners.utils import OpenAIUtils + +from langchain.prompts import ChatPromptTemplate +from langchain_core.output_parsers import StrOutputParser +from langchain.chat_models import ChatOpenAI +from dotenv import load_dotenv, find_dotenv +from langchain_core.runnables.base import RunnableSequence +from deprecated import deprecated + +@deprecated(version="2.4.1+", reason="Class is deprecated, use openai miner for reference on example miner.") +class LangchainMiner(BaseStreamPromptingMiner, OpenAIUtils): + """Langchain-based miner which uses OpenAI's API as the LLM. + This miner does not use any tools or external APIs when processing requests - it relies entirely on the models' own representation and world model. In some cases, this can produce lower quality results. + You should also install the dependencies for this miner, which can be found in the requirements.txt file in this directory. + """ + + @classmethod + def add_args(cls, parser: argparse.ArgumentParser): + """ + Adds OpenAI-specific arguments to the command line parser. + """ + super().add_args(parser) + + def __init__(self, config=None): + super().__init__(config=config) + + bt.logging.info(f"Initializing with model {self.config.neuron.model_id}...") + + if self.config.wandb.on: + self.identity_tags = ("openai_miner",) + (self.config.neuron.model_id,) + + _ = load_dotenv(find_dotenv()) + api_key = os.environ.get("OPENAI_API_KEY") + + # Set openai key and other args + self.model = ChatOpenAI( + api_key=api_key, + model_name=self.config.neuron.model_id, + max_tokens=self.config.neuron.max_tokens, + temperature=self.config.neuron.temperature, + ) + + self.system_prompt = self.config.neuron.system_prompt + self.accumulated_total_tokens = 0 + self.accumulated_prompt_tokens = 0 + self.accumulated_completion_tokens = 0 + self.accumulated_total_cost = 0 + + def forward(self, synapse: StreamPromptingSynapse) -> Awaitable: + async def _forward( + self, + message: str, + init_time: float, + timeout_threshold: float, + chain: RunnableSequence, + chain_formatter: Dict[str, str], + send: Send, + ): + buffer = [] + temp_completion = "" # for wandb logging + timeout_reached = False + + try: + # Langchain built in streaming. 'astream' also available for async + for token in chain.stream(chain_formatter): + buffer.append(token) + + if time.time() - init_time > timeout_threshold: + bt.logging.debug(f"⏰ Timeout reached, stopping streaming") + timeout_reached = True + break + + if len(buffer) == self.config.neuron.streaming_batch_size: + joined_buffer = "".join(buffer) + temp_completion += joined_buffer + bt.logging.debug(f"Streamed tokens: {joined_buffer}") + + await send( + { + "type": "http.response.body", + "body": joined_buffer.encode("utf-8"), + "more_body": True, + } + ) + buffer = [] + + if ( + buffer and not timeout_reached + ): # Don't send the last buffer of data if timeout. + joined_buffer = "".join(buffer) + await send( + { + "type": "http.response.body", + "body": joined_buffer.encode("utf-8"), + "more_body": False, + } + ) + + except Exception as e: + bt.logging.error(f"Error in forward: {e}") + if self.config.neuron.stop_on_forward_exception: + self.should_exit = True + + finally: + synapse_latency = time.time() - init_time + if self.config.wandb.on: + self.log_event( + timing=synapse_latency, + prompt=message, + completion=temp_completion, + system_prompt=self.system_prompt, + ) + + bt.logging.debug(f"📧 Message received, forwarding synapse: {synapse}") + + prompt = ChatPromptTemplate.from_messages( + [("system", self.system_prompt), ("user", "{input}")] + ) + chain = prompt | self.model | StrOutputParser() + + role = synapse.roles[-1] + message = synapse.messages[-1] + + chain_formatter = {"role": role, "input": message} + + init_time = time.time() + timeout_threshold = synapse.timeout + + token_streamer = partial( + _forward, + self, + message, + init_time, + timeout_threshold, + chain, + chain_formatter, + ) + return synapse.create_streaming_response(token_streamer) diff --git a/prompting/miners/openai_miner.py b/prompting/miners/openai_miner.py index 73bf1718..9afe0ea2 100644 --- a/prompting/miners/openai_miner.py +++ b/prompting/miners/openai_miner.py @@ -30,12 +30,12 @@ # import base miner class which takes care of most of the boilerplate from prompting.miners.utils import OpenAIUtils - -from langchain.prompts import ChatPromptTemplate -from langchain_core.output_parsers import StrOutputParser -from langchain.chat_models import ChatOpenAI from dotenv import load_dotenv, find_dotenv -from langchain_core.runnables.base import RunnableSequence +from openai import OpenAI +from typing import List, Dict +from traceback import print_exception + +# Define the type for a list of dictionaries class OpenAIMiner(BaseStreamPromptingMiner, OpenAIUtils): @@ -63,13 +63,8 @@ def __init__(self, config=None): api_key = os.environ.get("OPENAI_API_KEY") # Set openai key and other args - self.model = ChatOpenAI( - api_key=api_key, - model_name=self.config.neuron.model_id, - max_tokens=self.config.neuron.max_tokens, - temperature=self.config.neuron.temperature, - ) - + self.model = OpenAI(api_key=api_key) + self.system_prompt = self.config.neuron.system_prompt self.accumulated_total_tokens = 0 self.accumulated_prompt_tokens = 0 @@ -79,21 +74,45 @@ def __init__(self, config=None): def forward(self, synapse: StreamPromptingSynapse) -> Awaitable: async def _forward( self, - message: str, + synapse: StreamPromptingSynapse, init_time: float, timeout_threshold: float, - chain: RunnableSequence, - chain_formatter: Dict[str, str], send: Send, ): buffer = [] + accumulated_chunks = [] + accumulated_chunks_timings = [] + messages = [] temp_completion = "" # for wandb logging timeout_reached = False - - try: - # Langchain built in streaming. 'astream' also available for async - for token in chain.stream(chain_formatter): - buffer.append(token) + + + try: + system_prompt_message = [{ 'role': 'system', 'content': self.system_prompt }] + synapse_messages = [{'role': role, 'content': message} for role, message in zip(synapse.roles, synapse.messages)] + + messages = system_prompt_message + synapse_messages + + start_time = time.time() + stream_response = self.model.chat.completions.create( + model=self.config.neuron.model_id, + messages=messages, + temperature=self.config.neuron.temperature, + max_tokens=self.config.neuron.max_tokens, + stream=True + ) + + for chunk in stream_response: + chunk_content = chunk.choices[0].delta.content + + if chunk_content is None: + bt.logging.info("OpenAI returned chunk content with None") + continue + + accumulated_chunks.append(chunk_content) + accumulated_chunks_timings.append(time.time() - start_time) + + buffer.append(chunk_content) if time.time() - init_time > timeout_threshold: bt.logging.debug(f"⏰ Timeout reached, stopping streaming") @@ -128,6 +147,7 @@ async def _forward( except Exception as e: bt.logging.error(f"Error in forward: {e}") + bt.logging.error(print_exception(type(e), e, e.__traceback__)) if self.config.neuron.stop_on_forward_exception: self.should_exit = True @@ -135,34 +155,23 @@ async def _forward( synapse_latency = time.time() - init_time if self.config.wandb.on: self.log_event( + synapse=synapse, timing=synapse_latency, - prompt=message, - completion=temp_completion, - system_prompt=self.system_prompt, + messages=messages, + accumulated_chunks=accumulated_chunks, + accumulated_chunks_timings = accumulated_chunks_timings, ) - bt.logging.debug(f"📧 Message received, forwarding synapse: {synapse}") - - prompt = ChatPromptTemplate.from_messages( - [("system", self.system_prompt), ("user", "{input}")] - ) - chain = prompt | self.model | StrOutputParser() - - role = synapse.roles[-1] - message = synapse.messages[-1] - - chain_formatter = {"role": role, "input": message} - + bt.logging.debug(f"📧 Message received from {synapse.dendrite.hotkey}, IP: {synapse.dendrite.ip}; \nForwarding synapse: {synapse}") + init_time = time.time() timeout_threshold = synapse.timeout token_streamer = partial( _forward, self, - message, + synapse, init_time, - timeout_threshold, - chain, - chain_formatter, + timeout_threshold, ) return synapse.create_streaming_response(token_streamer) diff --git a/prompting/tasks/qa.py b/prompting/tasks/qa.py index 2fa29308..d8a6e91a 100644 --- a/prompting/tasks/qa.py +++ b/prompting/tasks/qa.py @@ -22,10 +22,11 @@ # Used to obtain the query (which is a followup question about the context) # TODO: we may not need the entire conversation history - we can sample a subset of it (first k messages, last k messages, etc.) FOLLOWUP_PROMPT_TEMPLATE = """ -Compose a single, specific question to continue the dialogue below. Adopt the persona of the original user, including their communication style and objectives. The question should be based on the previous exchanges and must not be answerable with a simple yes or no. +Compose a single, specific question to continue the dialogue below. Adopt the persona of the original user, reflecting their communication style and objectives. The question should be rooted in the previous exchanges and should not be answerable with a simple yes or no. -The question should require detailed knowledge of the conversation history for a correct response, emphasizing requests for clarification or additional details (e.g., 'What specific steps did you take?' or 'How did that situation resolve?'). Avoid referring to the subject by name and instead use indirect pronouns or descriptions (e.g., 'he,' 'she,' 'it'). Avoid answering the question yourself and refrain from providing new information not already discussed. +Ensure the question requires detailed knowledge of the conversation history for a correct response, focusing on requests for clarification or additional details (e.g., 'What specific steps did you take?', 'Are you sure?', 'How do you know that is true', or 'How did that situation resolve?'). Use indirect pronouns or descriptions to refer to subjects instead of their names. Avoid answering the question yourself and do not introduce new information not already discussed. +When asking a followup question, you should use pronouns or descriptions to refer to subjects instead of their names. You absolutely must not repeat the subject of the question in the followup question. For example, if the question is "What is the capital of France?", the followup question should not be "What is the population of France?". Instead, it should be "How many people live there?" or "What is its population?". # Context: {context} @@ -33,6 +34,7 @@ {history} """ + # Used to obtain reference answer REFERENCE_PROMPT_TEMPLATE = """\ Answer the question you will receive in detail, utilizing the following context. @@ -45,18 +47,20 @@ """ # TODO: We also need a special followup reference prompt (or just merge both) -# Used to obtain reference answer +# TODO: We should create followups using the specified llama3 chat template rather than feeding the message history through textually FOLLOWUP_REFERENCE_PROMPT_TEMPLATE = """\ -Answer the question you will receive in detail, utilizing the following context and conversation history as required. - -#Context: -{context} +You are a helpful assistant. Answer the question below in detail, prioritizing the use of the provided conversation history. The context is available for additional information if needed, but it may not always be relevant. # Conversation History: {history} +# Context (optional): +{context} + # Question: {question} + +Ensure your answer references relevant parts of the conversation history. Use the context only if it provides additional necessary information. """ @dataclass diff --git a/prompting/utils/config.py b/prompting/utils/config.py index a9382039..67ae5b94 100644 --- a/prompting/utils/config.py +++ b/prompting/utils/config.py @@ -20,9 +20,13 @@ import torch import argparse import bittensor as bt -from loguru import logger +import logging from prompting.tasks import TASKS +from bittensor.btlogging.defines import BITTENSOR_LOGGER_NAME + +logger = logging.getLogger(BITTENSOR_LOGGER_NAME) + def check_config(cls, config: "bt.Config"): r"""Checks/validates the config namespace object.""" @@ -42,20 +46,16 @@ def check_config(cls, config: "bt.Config"): if not os.path.exists(config.neuron.full_path): os.makedirs(config.neuron.full_path, exist_ok=True) - log_level_exists = "EVENTS" in logger._core.levels - if not config.neuron.dont_save_events and not log_level_exists: + if not config.neuron.dont_save_events: # Add custom event logger for the events. - logger.level("EVENTS", no=38, icon="📝") - logger.add( - os.path.join(config.neuron.full_path, "events.log"), - rotation=config.neuron.events_retention_size, - serialize=True, - enqueue=True, - backtrace=False, - diagnose=False, - level="EVENTS", - format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}", + event_handler = logging.FileHandler( + os.path.join(config.neuron.full_path, "events.log") ) + event_handler.setLevel(38) # Custom level + formatter = logging.Formatter("{asctime} | {levelname} | {message}", style="{") + event_handler.setFormatter(formatter) + logger.addHandler(event_handler) + logging.addLevelName(38, "EVENTS") def add_args(cls, parser): @@ -71,14 +71,14 @@ def add_args(cls, parser): help="Device to run on.", default="cuda" if torch.cuda.is_available() else "cpu", ) - + parser.add_argument( "--neuron.gpus", type=int, help="The number of visible GPUs to be considered in the llm initialization. This parameter currently reflects on the property `tensor_parallel_size` of vllm", default=1, ) - + parser.add_argument( "--neuron.llm_max_allowed_memory_in_gb", type=int, @@ -307,7 +307,7 @@ def add_validator_args(cls, parser): "--neuron.timeout", type=float, help="The timeout for each forward call in seconds.", - default=17, + default=15, ) parser.add_argument( @@ -373,14 +373,14 @@ def add_validator_args(cls, parser): "--wandb.project_name", type=str, help="The name of the project where you are sending the new run.", - default="alpha-validators", + default="prompting-validators", ) parser.add_argument( "--wandb.entity", type=str, help="The name of the project where you are sending the new run.", - default="opentensor-dev", + default="macrocosmos", ) parser.add_argument( @@ -396,7 +396,7 @@ def add_validator_args(cls, parser): help="Only query a single hotkey per ip.", default=False, ) - + parser.add_argument( "--neuron.forward_max_time", type=int, diff --git a/prompting/utils/logging.py b/prompting/utils/logging.py index d7029b89..50474b63 100644 --- a/prompting/utils/logging.py +++ b/prompting/utils/logging.py @@ -6,8 +6,11 @@ from dataclasses import asdict, dataclass from datetime import datetime from typing import List -from loguru import logger +import logging import prompting +from bittensor.btlogging.defines import BITTENSOR_LOGGER_NAME + +logger = logging.getLogger(BITTENSOR_LOGGER_NAME) @dataclass @@ -103,7 +106,7 @@ def reinit_wandb(self): def log_event(self, event): if not self.config.neuron.dont_save_events: - logger.log("EVENTS", "events", **event) + logger.log(38, event) if self.config.wandb.off: return diff --git a/requirements.txt b/requirements.txt index 7d11d95f..bb2b86b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ angle_emb==0.4.4 -bittensor==7.0.1 +bittensor==7.1.1 bs4==0.0.2 click==8.1.3 datasets==2.14.6 @@ -28,7 +28,6 @@ argostranslate==1.9.6 python-dotenv wikipedia_sections vllm -loguru argostranslate transformers==4.41.2 autoawq==0.2.5 diff --git a/tests/test_forward.py b/tests/test_forward.py index aa826a17..36d93495 100644 --- a/tests/test_forward.py +++ b/tests/test_forward.py @@ -2,12 +2,13 @@ import asyncio import sys from functools import partial -from prompting.forward import run_step +from prompting.forward import run_step, SINGLE_TURN_TASKS from neurons.validator import Validator from prompting.tasks import QuestionAnsweringTask from .fixtures.task import WIKI_CONTEXT from prompting.agent import HumanAgent from prompting.protocol import StreamPromptingSynapse +from prompting.tasks import TASKS sys.argv = [__file__, "--mock", "--wandb.off", "--neuron.tasks", "qa"] mock_neuron = Validator() @@ -59,3 +60,7 @@ def test_generate_reference_parallel_to_dendrite( assert network_and_reference_gen_time == pytest.approx( expected_forward_time, abs=1#0.1 ) + +def test_single_turn_tasks_in_tasks(): + # Test that SINGLE_TURN_TASKS is a subset of TASKS.keys() + assert set(SINGLE_TURN_TASKS).issubset(set(TASKS.keys()))