mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-31 17:27:42 +00:00
feat: use unified pickle cacher & move llm config into a isolated config (#424)
* simplify RDAgent conf * add unified cacher(untested) * fix small bugs * fix a bug * fix a small bug in runner * use hash_key = None to skip cache * fix CI * in factor execution, ignore cache when raise exception * add file locker to avoid mp calling * fix CI * use function __module__ name as folder in cache
This commit is contained in:
@@ -19,6 +19,7 @@ from rdagent.core.experiment import Task, Workspace
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.utils import multiprocessing_wrapper
|
||||
from rdagent.log import rdagent_logger as logger
|
||||
from rdagent.oai.llm_conf import LLM_SETTINGS
|
||||
from rdagent.oai.llm_utils import APIBackend
|
||||
|
||||
evaluate_prompts = Prompts(file_path=Path(__file__).parent.parent / "prompts.yaml")
|
||||
@@ -118,7 +119,7 @@ class FactorCodeEvaluator(FactorEvaluator):
|
||||
user_prompt=user_prompt,
|
||||
system_prompt=system_prompt,
|
||||
)
|
||||
> RD_AGENT_SETTINGS.chat_token_limit
|
||||
> LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
execution_feedback_to_render = execution_feedback_to_render[len(execution_feedback_to_render) // 2 :]
|
||||
else:
|
||||
@@ -521,7 +522,7 @@ class FactorFinalDecisionEvaluator(Evaluator):
|
||||
user_prompt=user_prompt,
|
||||
system_prompt=system_prompt,
|
||||
)
|
||||
> RD_AGENT_SETTINGS.chat_token_limit
|
||||
> LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
execution_feedback_to_render = execution_feedback_to_render[len(execution_feedback_to_render) // 2 :]
|
||||
else:
|
||||
|
||||
@@ -22,6 +22,7 @@ from rdagent.core.evolving_framework import EvolvingStrategy, QueriedKnowledge
|
||||
from rdagent.core.experiment import Workspace
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.utils import multiprocessing_wrapper
|
||||
from rdagent.oai.llm_conf import LLM_SETTINGS
|
||||
from rdagent.oai.llm_utils import APIBackend
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -160,7 +161,7 @@ class FactorEvolvingStrategy(MultiProcessEvolvingStrategy):
|
||||
session.build_chat_completion_message_and_calculate_token(
|
||||
user_prompt,
|
||||
)
|
||||
< RD_AGENT_SETTINGS.chat_token_limit
|
||||
< LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
break
|
||||
elif len(queried_former_failed_knowledge_to_render) > 1:
|
||||
@@ -281,7 +282,7 @@ class FactorEvolvingStrategyWithGraph(MultiProcessEvolvingStrategy):
|
||||
)
|
||||
if (
|
||||
session_summary.build_chat_completion_message_and_calculate_token(error_summary_user_prompt)
|
||||
< RD_AGENT_SETTINGS.chat_token_limit
|
||||
< LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
break
|
||||
elif len(queried_similar_error_knowledge_to_render) > 0:
|
||||
@@ -310,7 +311,7 @@ class FactorEvolvingStrategyWithGraph(MultiProcessEvolvingStrategy):
|
||||
session.build_chat_completion_message_and_calculate_token(
|
||||
user_prompt,
|
||||
)
|
||||
< RD_AGENT_SETTINGS.chat_token_limit
|
||||
< LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
break
|
||||
elif len(queried_former_failed_knowledge_to_render) > 1:
|
||||
|
||||
@@ -7,10 +7,10 @@ from jinja2 import Environment, StrictUndefined
|
||||
from rdagent.components.coder.factor_coder.CoSTEER.evolvable_subjects import (
|
||||
FactorEvolvingItem,
|
||||
)
|
||||
from rdagent.core.conf import RD_AGENT_SETTINGS
|
||||
from rdagent.core.prompts import Prompts
|
||||
from rdagent.core.scenario import Scenario
|
||||
from rdagent.log import rdagent_logger as logger
|
||||
from rdagent.oai.llm_conf import LLM_SETTINGS
|
||||
from rdagent.oai.llm_utils import APIBackend
|
||||
|
||||
scheduler_prompts = Prompts(file_path=Path(__file__).parent.parent / "prompts.yaml")
|
||||
@@ -68,7 +68,7 @@ def LLMSelect(
|
||||
user_prompt=user_prompt,
|
||||
system_prompt=system_prompt,
|
||||
)
|
||||
< RD_AGENT_SETTINGS.chat_token_limit
|
||||
< LLM_SETTINGS.chat_token_limit
|
||||
):
|
||||
break
|
||||
|
||||
|
||||
@@ -20,12 +20,6 @@ class FactorImplementSettings(BaseSettings):
|
||||
data_folder_debug: str = "git_ignore_folder/factor_implementation_source_data_debug"
|
||||
"""Path to the folder containing partial financial data (for debugging)"""
|
||||
|
||||
cache_location: str = "git_ignore_folder/factor_implementation_execution_cache"
|
||||
"""Path to the cache location"""
|
||||
|
||||
enable_execution_cache: bool = True
|
||||
"""Indicates whether to enable the execution cache"""
|
||||
|
||||
# TODO: the factor implement specific settings should not appear in this settings
|
||||
# Evolving should have a method specific settings
|
||||
# evolving related config
|
||||
|
||||
@@ -13,6 +13,7 @@ from rdagent.app.kaggle.conf import KAGGLE_IMPLEMENT_SETTING
|
||||
from rdagent.components.coder.factor_coder.config import FACTOR_IMPLEMENT_SETTINGS
|
||||
from rdagent.core.exception import CodeFormatError, CustomRuntimeError, NoOutputError
|
||||
from rdagent.core.experiment import Experiment, FBWorkspace, Task
|
||||
from rdagent.core.utils import cache_with_pickle
|
||||
from rdagent.log import rdagent_logger as logger
|
||||
from rdagent.oai.llm_utils import md5_hash
|
||||
|
||||
@@ -80,17 +81,21 @@ class FactorFBWorkspace(FBWorkspace):
|
||||
def __init__(
|
||||
self,
|
||||
*args,
|
||||
executed_factor_value_dataframe: pd.DataFrame = None,
|
||||
raise_exception: bool = False,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.executed_factor_value_dataframe = executed_factor_value_dataframe
|
||||
self.raise_exception = raise_exception
|
||||
|
||||
def execute(
|
||||
self, enable_cache: bool = FACTOR_IMPLEMENT_SETTINGS.enable_execution_cache, data_type: str = "Debug"
|
||||
) -> Tuple[str, pd.DataFrame]:
|
||||
def hash_func(self, data_type: str = "Debug") -> str:
|
||||
return (
|
||||
md5_hash(data_type + self.code_dict["factor.py"])
|
||||
if ("factor.py" in self.code_dict and not self.raise_exception)
|
||||
else None
|
||||
)
|
||||
|
||||
@cache_with_pickle(hash_func)
|
||||
def execute(self, data_type: str = "Debug") -> Tuple[str, pd.DataFrame]:
|
||||
"""
|
||||
execute the implementation and get the factor value by the following steps:
|
||||
1. make the directory in workspace path
|
||||
@@ -108,8 +113,6 @@ class FactorFBWorkspace(FBWorkspace):
|
||||
1. We will store the function's return value to ensure it behaves as expected.
|
||||
- The cached information will include a tuple with the following: (execution_feedback, executed_factor_value_dataframe, Optional[Exception])
|
||||
|
||||
parameters:
|
||||
enable_cache: if True, store the factor value in the instance variable, this feature is to be used in the gt implementation to avoid multiple execution on the same gt implementation
|
||||
"""
|
||||
super().execute()
|
||||
if self.code_dict is None or "factor.py" not in self.code_dict:
|
||||
@@ -118,31 +121,6 @@ class FactorFBWorkspace(FBWorkspace):
|
||||
else:
|
||||
return self.FB_CODE_NOT_SET, None
|
||||
with FileLock(self.workspace_path / "execution.lock"):
|
||||
if FACTOR_IMPLEMENT_SETTINGS.enable_execution_cache:
|
||||
# NOTE: cache the result for the same code and same data type
|
||||
target_file_name = md5_hash(data_type + self.code_dict["factor.py"])
|
||||
cache_file_path = Path(FACTOR_IMPLEMENT_SETTINGS.cache_location) / f"{target_file_name}.pkl"
|
||||
Path(FACTOR_IMPLEMENT_SETTINGS.cache_location).mkdir(exist_ok=True, parents=True)
|
||||
if enable_cache and cache_file_path.exists():
|
||||
cached_res = pickle.load(open(cache_file_path, "rb"))
|
||||
|
||||
if len(cached_res) == 2:
|
||||
# NOTE: this is trying to be compatible with previous results.
|
||||
# Previously, the exception is not saved. we should not enable the cache mechanism
|
||||
# othersise we can raise the exception directly.
|
||||
if self.raise_exception:
|
||||
pass # pass to disable the cache mechanism
|
||||
else:
|
||||
self.executed_factor_value_dataframe = cached_res[1]
|
||||
return cached_res
|
||||
else:
|
||||
# NOTE: (execution_feedback, executed_factor_value_dataframe, Optional[Exception])
|
||||
if self.raise_exception and cached_res[-1] is not None:
|
||||
raise cached_res[-1]
|
||||
else:
|
||||
self.executed_factor_value_dataframe = cached_res[1]
|
||||
return cached_res[:2]
|
||||
|
||||
if self.target_task.version == 1:
|
||||
source_data_path = (
|
||||
Path(
|
||||
@@ -220,14 +198,6 @@ class FactorFBWorkspace(FBWorkspace):
|
||||
else:
|
||||
execution_error = NoOutputError(execution_feedback)
|
||||
|
||||
if enable_cache and executed_factor_value_dataframe is not None:
|
||||
self.executed_factor_value_dataframe = executed_factor_value_dataframe
|
||||
|
||||
if FACTOR_IMPLEMENT_SETTINGS.enable_execution_cache:
|
||||
pickle.dump(
|
||||
(execution_feedback, executed_factor_value_dataframe, execution_error),
|
||||
open(cache_file_path, "wb"),
|
||||
)
|
||||
return execution_feedback, executed_factor_value_dataframe
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
||||
Reference in New Issue
Block a user