mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-30 08:57:44 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d89fb2a82e | |||
| 976b86664f | |||
| 05b584b184 | |||
| c701a8105b |
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## [0.6.1](https://github.com/microsoft/RD-Agent/compare/v0.6.0...v0.6.1) (2025-06-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix mount ([#1001](https://github.com/microsoft/RD-Agent/issues/1001)) ([4ae2f13](https://github.com/microsoft/RD-Agent/commit/4ae2f1303dfcbaea53d459be7c8e85bf85ce5f4f))
|
||||
* handle the bug of wrong dag_parant index ([#996](https://github.com/microsoft/RD-Agent/issues/996)) ([bda12ff](https://github.com/microsoft/RD-Agent/commit/bda12ffecf9ae116e0d04eece0c6a1b61413d916))
|
||||
* improve log folder sorting and selection UX ([#993](https://github.com/microsoft/RD-Agent/issues/993)) ([b116807](https://github.com/microsoft/RD-Agent/commit/b11680777f116b6c40f9e535e0da10c186c95050))
|
||||
|
||||
## [0.6.0](https://github.com/microsoft/RD-Agent/compare/v0.5.0...v0.6.0) (2025-06-26)
|
||||
|
||||
|
||||
|
||||
@@ -105,14 +105,21 @@ class FactorReportLoop(FactorRDLoop, metaclass=LoopMeta):
|
||||
self.judge_pdf_data_items = [i for i in Path(report_folder).rglob("*.pdf")]
|
||||
|
||||
self.loop_n = min(len(self.judge_pdf_data_items), FACTOR_FROM_REPORT_PROP_SETTING.report_limit)
|
||||
self.shift_report = (
|
||||
0 # some reports does not contain viable factor, so we ship some of them to avoid infinite loop
|
||||
)
|
||||
|
||||
async def direct_exp_gen(self, prev_out: dict[str, Any]):
|
||||
while True:
|
||||
if self.get_unfinished_loop_cnt(self.loop_idx) < RD_AGENT_SETTINGS.get_max_parallel():
|
||||
report_file_path = self.judge_pdf_data_items[self.loop_idx]
|
||||
report_file_path = self.judge_pdf_data_items[self.loop_idx + self.shift_report]
|
||||
logger.info(f"Processing number {self.loop_idx} report: {report_file_path}")
|
||||
exp = extract_hypothesis_and_exp_from_reports(str(report_file_path))
|
||||
if exp is None:
|
||||
self.shift_report += 1
|
||||
self.loop_n -= 1
|
||||
if self.loop_n < 0: # NOTE: on every step, we self.loop_n -= 1 at first.
|
||||
raise self.LoopTerminationError("Reach stop criterion and stop loop")
|
||||
continue
|
||||
exp.based_experiments = [QlibFactorExperiment(sub_tasks=[], hypothesis=exp.hypothesis)] + [
|
||||
t[0] for t in self.trace.hist if t[1]
|
||||
|
||||
+14
-10
@@ -617,18 +617,22 @@ def stdout_win(loop_id: int):
|
||||
st.code(v, language="log", wrap_lines=True)
|
||||
|
||||
|
||||
def get_folders_sorted(log_path):
|
||||
"""缓存并返回排序后的文件夹列表,并加入进度打印"""
|
||||
def get_folders_sorted(log_path, sort_by_time=False):
|
||||
"""
|
||||
Cache and return the sorted list of folders, with progress printing.
|
||||
:param log_path: Log path
|
||||
:param sort_by_time: Whether to sort by time, default False (sort by name)
|
||||
"""
|
||||
if not log_path.exists():
|
||||
st.toast(f"Path {log_path} does not exist!")
|
||||
return []
|
||||
with st.spinner("正在加载文件夹列表..."):
|
||||
folders = sorted(
|
||||
(folder for folder in log_path.iterdir() if is_valid_session(folder)),
|
||||
key=lambda folder: folder.stat().st_mtime,
|
||||
reverse=True,
|
||||
)
|
||||
st.write(f"找到 {len(folders)} 个文件夹")
|
||||
with st.spinner("Loading folder list..."):
|
||||
folders = [folder for folder in log_path.iterdir() if is_valid_session(folder)]
|
||||
if sort_by_time:
|
||||
folders = sorted(folders, key=lambda folder: folder.stat().st_mtime, reverse=True)
|
||||
else:
|
||||
folders = sorted(folders, key=lambda folder: folder.name)
|
||||
st.write(f"Found {len(folders)} folders")
|
||||
return [folder.name for folder in folders]
|
||||
|
||||
|
||||
@@ -659,7 +663,7 @@ with st.sidebar:
|
||||
if not state.log_folder.exists():
|
||||
st.warning(f"Path {state.log_folder} does not exist!")
|
||||
else:
|
||||
folders = get_folders_sorted(state.log_folder)
|
||||
folders = get_folders_sorted(state.log_folder, sort_by_time=False)
|
||||
if "selection" in st.query_params:
|
||||
default_index = (
|
||||
folders.index(st.query_params["selection"]) if st.query_params["selection"] in folders else 0
|
||||
|
||||
@@ -222,7 +222,6 @@ class DataScienceRDLoop(RDLoop):
|
||||
e = prev_out.get(self.EXCEPTION_KEY, None)
|
||||
if e is None:
|
||||
exp = prev_out["running"]
|
||||
self.trace.hist.append((exp, prev_out["feedback"]))
|
||||
|
||||
# NOTE: we put below operations on selections here, instead of out of the if-else block,
|
||||
# to fit the corner case that the trace will be reset
|
||||
@@ -232,8 +231,16 @@ class DataScienceRDLoop(RDLoop):
|
||||
self.trace.set_current_selection(exp.local_selection)
|
||||
self.trace.sync_dag_parent_and_hist()
|
||||
|
||||
self.trace.hist.append((exp, prev_out["feedback"]))
|
||||
|
||||
else:
|
||||
exp: DSExperiment = prev_out["direct_exp_gen"] if isinstance(e, CoderError) else prev_out["coding"]
|
||||
|
||||
# set the local selection to the trace as global selection, then set the DAG parent for the trace
|
||||
if exp.local_selection is not None:
|
||||
self.trace.set_current_selection(exp.local_selection)
|
||||
self.trace.sync_dag_parent_and_hist()
|
||||
|
||||
self.trace.hist.append(
|
||||
(
|
||||
exp,
|
||||
@@ -241,11 +248,6 @@ class DataScienceRDLoop(RDLoop):
|
||||
)
|
||||
)
|
||||
|
||||
# set the local selection to the trace as global selection, then set the DAG parent for the trace
|
||||
if exp.local_selection is not None:
|
||||
self.trace.set_current_selection(exp.local_selection)
|
||||
self.trace.sync_dag_parent_and_hist()
|
||||
|
||||
if self.trace.sota_experiment() is None:
|
||||
if DS_RD_SETTING.coder_on_whole_pipeline:
|
||||
# check if feedback is not generated
|
||||
|
||||
@@ -602,6 +602,10 @@ class DockerConf(EnvConf):
|
||||
default_entry: str # the entry point of the image
|
||||
|
||||
extra_volumes: dict = {}
|
||||
"""It accept a dict of volumes, which can be either
|
||||
{<host_path>: <container_path>} or
|
||||
{<host_path>: {"bind": <container_path>, "mode": <mode, ro/rw/default is extra_volume_mode>}}
|
||||
"""
|
||||
extra_volume_mode: str = "ro" # by default. only the mount_path should be writable, others are changed to read-only
|
||||
# Sometime, we need maintain some extra data for the workspace.
|
||||
# And the extra data may be shared and the downloading can be time consuming.
|
||||
@@ -662,7 +666,9 @@ class QlibDockerConf(DockerConf):
|
||||
image: str = "local_qlib:latest"
|
||||
mount_path: str = "/workspace/qlib_workspace/"
|
||||
default_entry: str = "qrun conf.yaml"
|
||||
extra_volumes: dict = {str(Path("~/.qlib/").expanduser().resolve().absolute()): "/root/.qlib/"}
|
||||
extra_volumes: dict = {
|
||||
str(Path("~/.qlib/").expanduser().resolve().absolute()): {"bind": "/root/.qlib/", "mode": "rw"}
|
||||
}
|
||||
shm_size: str | None = "16g"
|
||||
enable_gpu: bool = True
|
||||
enable_cache: bool = False
|
||||
@@ -854,12 +860,12 @@ class DockerEnv(Env[DockerConf]):
|
||||
|
||||
if self.conf.extra_volumes is not None:
|
||||
for lp, rp in self.conf.extra_volumes.items():
|
||||
volumes[lp] = {"bind": rp, "mode": self.conf.extra_volume_mode}
|
||||
volumes[lp] = rp if isinstance(rp, dict) else {"bind": rp, "mode": self.conf.extra_volume_mode}
|
||||
cache_path = "/tmp/sample" if "/sample/" in "".join(self.conf.extra_volumes.keys()) else "/tmp/full"
|
||||
Path(cache_path).mkdir(parents=True, exist_ok=True)
|
||||
volumes[cache_path] = {"bind": T("scenarios.data_science.share:scen.cache_path").r(), "mode": "rw"}
|
||||
for lp, rp in running_extra_volume.items():
|
||||
volumes[lp] = {"bind": rp, "mode": self.conf.extra_volume_mode}
|
||||
volumes[lp] = rp if isinstance(rp, dict) else {"bind": rp, "mode": self.conf.extra_volume_mode}
|
||||
|
||||
volumes = normalize_volumes(cast(dict[str, str | dict[str, str]], volumes), self.conf.mount_path)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user