-
-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Init todo * Evaluation & dataset * Generate new data * dataset generation * add the result * Analysis * Factor update * Updates * Reformat analysis.py * CI fix * Further Optimised Model Workflow by Incorporating Feedbacks on Exp Task Card * Rebasing To build the extraction & implementation demo * Revised for clean code * Revised further to show "Knowledge" * Revised to make model_research_copilot better * Further Optimised Model Workflow by Incorporating Feedbacks on Exp Task Card * Rebasing To build the extraction & implementation demo * Revised for clean code * Revised further to show "Knowledge" * Revised to make model_research_copilot better --------- Co-authored-by: Young <[email protected]> Co-authored-by: Taozhi Wang <[email protected]> Co-authored-by: you-n-g <[email protected]> Co-authored-by: cyncyw <[email protected]>
- Loading branch information
1 parent
a339fd8
commit 756552c
Showing
16 changed files
with
193 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from pathlib import Path | ||
|
||
from rdagent.components.coder.model_coder.model import ( | ||
ModelExperiment, | ||
) | ||
from rdagent.core.prompts import Prompts | ||
from rdagent.core.scenario import Scenario | ||
|
||
prompt_dict = Prompts(file_path=Path(__file__).parent / "prompts.yaml") | ||
|
||
class GeneralModelScenario(Scenario): | ||
@property | ||
def background(self) -> str: | ||
return prompt_dict["general_model_background"] | ||
|
||
@property | ||
def source_data(self) -> str: | ||
raise NotImplementedError("source_data of GeneralModelScenario is not implemented") | ||
|
||
@property | ||
def output_format(self) -> str: | ||
return prompt_dict["general_model_output_format"] | ||
|
||
@property | ||
def interface(self) -> str: | ||
return prompt_dict["general_model_interface"] | ||
|
||
@property | ||
def simulator(self) -> str: | ||
return prompt_dict["general_model_simulator"] | ||
|
||
@property | ||
def rich_style_description(self)->str: | ||
return ''' | ||
# General Model Scenario | ||
## Overview | ||
This demo automates the extraction and iterative development of models from academic papers, ensuring functionality and correctness. | ||
### Scenario: Auto-Developing Model Code from Academic Papers | ||
#### Overview | ||
This scenario automates the development of PyTorch models by reading academic papers or other sources. It supports various data types, including tabular, time-series, and graph data. The primary workflow involves two main components: the Reader and the Coder. | ||
#### Workflow Components | ||
1. **Reader** | ||
- Parses and extracts relevant model information from academic papers or sources, including architectures, parameters, and implementation details. | ||
- Uses Large Language Models to convert content into a structured format for the Coder. | ||
2. **Evolving Coder** | ||
- Translates structured information from the Reader into executable PyTorch code. | ||
- Utilizes an evolving coding mechanism to ensure correct tensor shapes, verified with sample input tensors. | ||
- Iteratively refines the code to align with source material specifications. | ||
#### Supported Data Types | ||
- **Tabular Data:** Structured data with rows and columns, such as spreadsheets or databases. | ||
- **Time-Series Data:** Sequential data points indexed in time order, useful for forecasting and temporal pattern recognition. | ||
- **Graph Data:** Data structured as nodes and edges, suitable for network analysis and relational tasks. | ||
''' | ||
|
||
def get_scenario_all_desc(self) -> str: | ||
return f"""Background of the scenario: | ||
{self.background} | ||
The interface you should follow to write the runnable code: | ||
{self.interface} | ||
The output of your code should be in the format: | ||
{self.output_format} | ||
The simulator user can use to test your model: | ||
{self.simulator} | ||
""" |
27 changes: 18 additions & 9 deletions
27
rdagent/app/model_extraction_and_code/model_extraction_and_implementation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,30 @@ | ||
# %% | ||
from dotenv import load_dotenv | ||
|
||
load_dotenv(override=True) | ||
|
||
from rdagent.components.coder.model_coder.task_loader import ( | ||
ModelExperimentLoaderFromPDFfiles, | ||
) | ||
from rdagent.scenarios.qlib.developer.model_coder import QlibModelCoSTEER | ||
from rdagent.scenarios.qlib.experiment.model_experiment import QlibModelScenario | ||
|
||
from rdagent.app.model_extraction_and_code.GeneralModel import GeneralModelScenario | ||
from rdagent.components.document_reader.document_reader import extract_first_page_screenshot_from_pdf | ||
from rdagent.log import rdagent_logger as logger | ||
import fire | ||
|
||
def extract_models_and_implement(report_file_path: str = "../test_doc") -> None: | ||
scenario = QlibModelScenario() | ||
exp = ModelExperimentLoaderFromPDFfiles().load(report_file_path) | ||
exp = QlibModelCoSTEER(scenario).develop(exp) | ||
def extract_models_and_implement(report_file_path: str = "/home/v-xisenwang/RD-Agent/rdagent/app/model_extraction_and_code/test_doc1.pdf") -> None: | ||
with logger.tag("r"): | ||
# Save Relevant Images | ||
img = extract_first_page_screenshot_from_pdf(report_file_path) | ||
logger.log_object(img, tag="pdf_image") | ||
scenario = GeneralModelScenario() | ||
logger.log_object(scenario, tag="scenario") | ||
with logger.tag("d"): | ||
exp = ModelExperimentLoaderFromPDFfiles().load(report_file_path) | ||
logger.log_object(exp, tag="load_experiment") | ||
exp = QlibModelCoSTEER(scenario).develop(exp) | ||
logger.log_object(exp, tag="developed_experiment") | ||
return exp | ||
|
||
|
||
import fire | ||
|
||
if __name__ == "__main__": | ||
fire.Fire(extract_models_and_implement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
general_model_background: |- | ||
The general model is a flexible and comprehensive framework designed to integrate factor-based, model-based, and graph-based approaches in quantitative investment. It allows users to define custom models that leverage various financial factors to predict the returns and risks of portfolios or single assets. These models are central to many advanced quantitative investment strategies and can be adapted to a wide range of use cases, from factor-based alpha generation to complex deep learning predictions. | ||
Each general model incorporates the following components: | ||
1. Name: The name of the model. | ||
2. Description: A detailed description of the model. | ||
3. Factors: The financial factors used as inputs, including their definitions and formulations. | ||
4. Architecture: The structure of the machine learning, deep learning, or graph-based model. | ||
5. Hyperparameters: The hyperparameters used in the model, such as learning rate, number of epochs, etc. | ||
6. ModelType: The type of the model, "Tabular" for tabular data, "TimeSeries" for time series data, or "Graph" for graph data. | ||
The general model should provide clear and detailed documentation of its factors, architecture, and hyperparameters. Each model should have a fixed architecture and hyperparameters to ensure reproducibility and consistency. | ||
general_model_interface: |- | ||
Your python code should follow the interface to better interact with the user's system. It should be a pytorch model. | ||
Your code should contain several parts: | ||
1. The import part: import the necessary libraries. | ||
2. A class which is a sub-class of pytorch.nn.Module. This class should have an init function and a forward function which inputs a tensor and outputs a tensor. | ||
3. Set a variable called "model_cls" to the class you defined. | ||
The user will save your code into a python file called "model.py". Then the user imports model_cls in file "model.py" after setting the cwd into the directory: | ||
```python | ||
from model import model_cls | ||
So your python code should follow the pattern: | ||
class XXXModel(torch.nn.Module): | ||
... | ||
model_cls = XXXModel | ||
The model has three types, "Tabular" for tabular data, "TimeSeries" for time series data, and "Graph" for graph data. | ||
The input shape to a tabular model is (batch_size, num_features). | ||
The input shape to a time series model is (batch_size, num_features, num_timesteps). | ||
The input to a graph model are two tensors. | ||
node_feature: a tensor of shape (batch_size, num_nodes, num_features) | ||
edge_index: a tensor of shape (2, num_edges) | ||
The batch_size is a dynamic value which is determined by the input of the forward function. | ||
The output shape of the model should be (batch_size, 1). | ||
The "num_features", "num_timesteps", and "num_nodes" are static and will be provided to the model through the init function. | ||
User will initialize the tabular model with the following code: | ||
model = model_cls(num_features=num_features) | ||
User will initialize the time series model with the following code: | ||
model = model_cls(num_features=num_features, num_timesteps=num_timesteps) | ||
User will initialize the graph model with the following code: | ||
model = model_cls(num_features=num_features, num_nodes=num_nodes) | ||
No other parameters will be passed to the model, so give other parameters a default value or make them static. | ||
When dealing with a time series model, remember to permute the input tensor since the input tensor is in the shape of (batch_size, num_features, num_timesteps) and a normal time series model is expecting the input tensor in the shape of (batch_size, num_timesteps, num_features). | ||
Don't write any try-except block in your python code. The user will catch the exception message and provide the feedback to you. Also, don't write a main function in your python code. The user will call the forward method in the model_cls to get the output tensor. | ||
Please note that your model should only use current features as input. The user will provide the input tensor to the model's forward function. | ||
general_model_output_format: |- | ||
Your output should be a tensor with shape (batch_size, 1). | ||
The output tensor should be saved in a file named "output.pth" in the same directory as your python file. | ||
The user will evaluate the shape of the output tensor, so the tensor read from "output.pth" should be 8 numbers. | ||
general_model_simulator: |- | ||
The models are not loaded and backtested. That said, pay attention to its architecture. | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters