mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-27 23:47:46 +00:00
f78175b37a
* refine ds modal for more cases: eval and es * update model template * prompts for model and ensemble * fix a bug * fix a bug * init: ds workflow evovingstrategy * Adding ensemble (#505) * Initial Draft * Updating logic for init * Revising * Successful Testing * Updating to use the latest & right class * bug: bug-fixing for testing * data science loop changes * data science loop base * ds loop feedback * fix * remove measure_time because it's duplicated (in LoopBase) * add the knowledge query for data_loader & feature * edit ds workflow evaluator * data_loader bug fix * stop evolving when all tasks completed * llm app change * fix break all complete strategy * Adding queried knowledge (#508) Co-authored-by: XianBW <36835909+XianBW@users.noreply.github.com> * fix loop bug * ds workflow evaluator; test; refine prompts * workflow spec * fix ci * feature task changes * ds loop change * fix a bug in feat * add query knowledge for model and workflow * llm_debug info(for show) using pickle instead of json * remove NextLoopException * loop change * coder raise CoderError when all sub_tasks failed * rename code_dict to file_dict in FBWorkspace * add CoSTEER unittest * now show self.version in Task.get_task_information(), simplify CoSTEER sub tasks definition * remove some properties in ModelTask, add model_type in it. * fix llm app bug * llm web app bug fix * ds loop bug fix * fix: give component code to feature&ens eval * loop catch error bug * rename load_from_raw_data to load_data * feat: Add debug data creation functionality for data science scenarios * support local folder (#511) * support local folder * remove unnecessary random * KaggleScen Subclass * small fix * use template for style description * update default scen to kaggle * update sample data script * make sure frac < 1 * fix a bug * feature spec changes * fix * changeimport order * clear unnecessary std outputs * fix a typo * create sample folder after unzip kaggle data * feature/model test script update * Align the data types across modules. * fix a bug in model eval * show line number * move sample entry point to app * spec & model prompt changes * Refine the competition specification to address the data type problem and the coherence issue. * fix some bugs * add file filter in FBworkspace.code property * support non-binary prediction * avoid too much warnings * fix a bug in ensemble module * filtered the knowledge query in all modules * delete RAG in idea proposal * refine the code in ensemble * show exp workspace in llm_st * exp_gen bug fix * feedback bug fix * use `feature` instead of `feat01` * Trace & method of judging if exp is completed change * fix a bug in package calling and execute ci * fix code * bug fix * bug fix * fix a bug * fix some bugs * fix a bug * refactor: Enhance error handling and feedback in data science loop * support different use_azure on chat and embedding models * multi-model proposal logic * fix a small syntax error * loopBase and some changes * ensemble scores change * fbworkspace.code -> .all_codes * use all model codes in workflow coder * check scores.csv's keys(model_names) * model name changes * add a todo in ensemble test * sota_exp changes * give model info in exp gen * add runner time limit * config using debug data or not in evals * exp to feedback base * add feature code when writing model task * small problem * copying during sampling * update * refactor: Simplify code handling and improve workspace management * model part output fix * print model's execution time * bug fix * ensemble test fix * ens small change * ens_test bug fix * Refine partial expansion logic to display only a few subfolders when their structure is uniform, improving readability in nested directories. * several update on prompts * sample subfolders * Filter the stdout after code execution to remove irrelevant information e.g. progress bars, whitespace characters, excessive line breaks. * Add some more prompts and comments * several update on the first init rounds * model timeout as error * fix pattern of getting model codes in workspace * small bux fix on model prompts * remove get_code_with_key since we have regex pattern * fix: Correct tqdm progress bar update logic in LoopBase class * feat: Add diff generation and enhance feedback mechanism in data science loop * update some fix to model and workflow prompts * refine the logic of progress bar filter * add last_successful_exp in exp_gen * fix a one line bug * add a hint in prompt * fix data sample for bms * fix data sample for bms * hypothesis small fix * crawler readme update * fix component gen * fix bug * annotation change * load description.md if it exists * refactor: Simplify SOTA description handling in feedback and prompts * refactor: Use shared templates for feedback and experiment descriptions * change webapp for model codes changes * update proposal * add timeout message for docker run output * fix * refine the code in docker time processing * use .shape instead of len() when do shape eval * won't change size during iteration * support bson sample * sample support jsonl and bson * add former_code to coder prompts * a little speed us in debug data creating * filter progress bar when eval ens and main * avoid costeer makes no change to former code * fix several log error * add timeout judge threshold * fix some bugs in the evaluation of component output shapes * File structure for supporting litellm (#517) Co-authored-by: Young <afe.young@gmail.com> * ignore submission and show processing * ignore submission and show processing * add efficiency notice * refactor: Enhance error message with detailed feedback summary * refactor: Simplify component handling in DSExpGen class * refactor: Update code structure and add docstring for clarity * reserve one sample to each label in data sampling * add Evaluation info * refine costeer code to avoid giving same code twice * use raw_description as plain text * add a prompt hint to avoid same dict key * model task name bug in first model exp gen * fix a typo * add some debug info in costeer tests * task init change * enhance data sampling * refine the code in data_loader * more reasonable loop * fix a bug in data folder description * add error msg & traceback to execution feedback * fix llm error msg detection * add task information to costeer eval & add cache to docker run(use zipfile to store the whole workspace) * fix CI first round * fix CI second round * use txt to store test script to avoid pytest * remove zipfile in requirements * add azure.identity to requirements * ignore debug web page * component test changes * remove redundent task_desc in model coder * feat: Add APE module and prompts for automated prompt engineering * fix: Update .gitignore and improve text formatting in eval.py * refactor: Update print output and improve code comments and imports * style: Fix string formatting and import order in ape.py and fmt.py * exclude ape * add a data folder notice * reduce unnecessary output to stdout * refine the code of describe_data_folder * fix ci * style: streamlit style update (#522) * streamlit style update * fix import * fix format * fix llm_st loop progress bar * debugapp small change * fix model str * refine some prompts * fix model str * fix CI * refine the logic associated with the data_folder * fix ci * small change * set filter_progress_bar as default in execute * model proposal with workflow * add submission check in workflow eval * fix bug * small change * fix CI * fix CI * refactor: Move generate_diff to utils and update DSExpGen logic * more reasonable prompt describing metric direction * fix a minor jinja2 bug * quick fix exp_gen bugs * fix the following bug * fix * fix some bugs * remove workflow from model * add pending_tasks_list in data science to enable coding model and workflow * refine the code for handling JSON-formatted data descriptions * assert with information * ensure correct csv file name * add logging to help record the output * log competition * add log tag for debug llm app * test: Test ds refactor ll (#523) * fix bugs to former scenario * fix a bug because coding in rdloop changed * fix the bug when feedback gets no hypothesis * fix trace structure * change all trace hist when merging hypothesis to experiments * ignore some error in ruff * fix kaggle scenario bugs * refine one line * another bug * another small bug * fix ui bugs * chage kaggle train.py path --------- Co-authored-by: Xu Yang <peteryang@vip.qq.com> * fix CI * Update rdagent/app/data_science/loop.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add samplecsv into spec prompts * fix CI --------- Co-authored-by: TPLin22 <tplin2@163.com> Co-authored-by: yuanteli <1957922024@qq.com> Co-authored-by: Xisen Wang <118058822+xisen-w@users.noreply.github.com> Co-authored-by: Bowen Xian <xianbowen@outlook.com> Co-authored-by: Xu Yang <peteryang@vip.qq.com> Co-authored-by: XianBW <36835909+XianBW@users.noreply.github.com> Co-authored-by: Tim <illking@foxmail.com> Co-authored-by: 炼金术师华华 <37462254+YeewahChan@users.noreply.github.com> Co-authored-by: Linlang <30293408+SunsetWolf@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
254 lines
8.9 KiB
Python
254 lines
8.9 KiB
Python
import argparse
|
|
import json
|
|
import pickle
|
|
import re
|
|
import time
|
|
from pathlib import Path
|
|
|
|
import streamlit as st
|
|
from streamlit import session_state
|
|
|
|
st.set_page_config(layout="wide", page_title="debug_llm", page_icon="🎓", initial_sidebar_state="expanded")
|
|
|
|
# 获取 log_path 参数
|
|
parser = argparse.ArgumentParser(description="RD-Agent Streamlit App")
|
|
parser.add_argument("--log_dir", type=str, help="Path to the log directory")
|
|
args = parser.parse_args()
|
|
|
|
|
|
@st.cache_data
|
|
def get_folders_sorted(log_path):
|
|
"""缓存并返回排序后的文件夹列表,并加入进度打印"""
|
|
with st.spinner("正在加载文件夹列表..."):
|
|
folders = sorted(
|
|
(folder for folder in log_path.iterdir() if folder.is_dir() and list(folder.iterdir())),
|
|
key=lambda folder: folder.stat().st_mtime,
|
|
reverse=True,
|
|
)
|
|
st.write(f"找到 {len(folders)} 个文件夹")
|
|
return [folder.name for folder in folders]
|
|
|
|
|
|
# 设置主日志路径
|
|
main_log_path = Path(args.log_dir) if args.log_dir else Path("./log")
|
|
if not main_log_path.exists():
|
|
st.error(f"Log dir {main_log_path} does not exist!")
|
|
st.stop()
|
|
|
|
if "data" not in session_state:
|
|
session_state.data = []
|
|
if "log_path" not in session_state:
|
|
session_state.log_path = None
|
|
|
|
tlist = []
|
|
|
|
|
|
def load_data():
|
|
"""加载数据到 session_state 并显示进度"""
|
|
log_file = main_log_path / session_state.log_path / "debug_llm.pkl"
|
|
try:
|
|
with st.spinner(f"正在加载数据文件 {log_file}..."):
|
|
start_time = time.time()
|
|
with open(log_file, "rb") as f:
|
|
session_state.data = pickle.load(f)
|
|
st.success(f"数据加载完成!耗时 {time.time() - start_time:.2f} 秒")
|
|
st.session_state["current_loop"] = 1
|
|
except Exception as e:
|
|
session_state.data = [{"error": str(e)}]
|
|
st.error(f"加载数据失败: {e}")
|
|
|
|
|
|
# UI - Sidebar
|
|
with st.sidebar:
|
|
st.markdown(":blue[**Log Path**]")
|
|
manually = st.toggle("Manual Input")
|
|
if manually:
|
|
st.text_input("log path", key="log_path", label_visibility="collapsed")
|
|
else:
|
|
folders = get_folders_sorted(main_log_path)
|
|
st.selectbox(f"**Select from {main_log_path.absolute()}**", folders, key="log_path")
|
|
|
|
if st.button("Refresh Data"):
|
|
load_data()
|
|
st.rerun()
|
|
|
|
expand_all = st.toggle("Expand All", key="expand_all")
|
|
|
|
|
|
# Helper functions
|
|
def show_text(text, lang=None):
|
|
"""显示文本代码块"""
|
|
if lang:
|
|
st.code(text, language=lang, wrap_lines=True)
|
|
elif "\n" in text:
|
|
st.code(text, language="python", wrap_lines=True)
|
|
else:
|
|
st.code(text, language="html", wrap_lines=True)
|
|
|
|
|
|
def highlight_prompts_uri(uri):
|
|
"""高亮 URI 的格式"""
|
|
parts = uri.split(":")
|
|
return f"**{parts[0]}:**:green[**{parts[1]}**]"
|
|
|
|
|
|
def extract_loopid_func_name(tag):
|
|
"""提取 Loop ID 和函数名称"""
|
|
match = re.search(r"Loop_(\d+)\.(\w+)\.", tag)
|
|
return match.groups() if match else (None, None)
|
|
|
|
|
|
def extract_evoid(tag):
|
|
"""提取 EVO ID"""
|
|
match = re.search(r"\.evo_loop_(\d+)\.", tag)
|
|
return match.group(1) if match else None
|
|
|
|
|
|
# Display Data
|
|
progress_text = st.empty()
|
|
progress_bar = st.progress(0)
|
|
|
|
# 每页展示一个 Loop
|
|
LOOPS_PER_PAGE = 1
|
|
|
|
# 获取所有的 Loop ID
|
|
loop_groups = {}
|
|
for i, d in enumerate(session_state.data):
|
|
tag = d["tag"]
|
|
loop_id, _ = extract_loopid_func_name(tag)
|
|
if loop_id:
|
|
if loop_id not in loop_groups:
|
|
loop_groups[loop_id] = []
|
|
loop_groups[loop_id].append(d)
|
|
|
|
# 按 Loop ID 排序
|
|
sorted_loop_ids = sorted(loop_groups.keys(), key=int) # 假设 Loop ID 是数字
|
|
total_loops = len(sorted_loop_ids)
|
|
total_pages = total_loops # 每页展示一个 Loop
|
|
|
|
if total_pages:
|
|
# 初始化 current_loop
|
|
if "current_loop" not in st.session_state:
|
|
st.session_state["current_loop"] = 1
|
|
|
|
# Loop 导航按钮
|
|
col1, col2, col3, col4, col5 = st.sidebar.columns([1.2, 1, 2, 1, 1.2])
|
|
|
|
with col1:
|
|
if st.button("|<"): # 首页
|
|
st.session_state["current_loop"] = 1
|
|
with col2:
|
|
if st.button("<") and st.session_state["current_loop"] > 1: # 上一页
|
|
st.session_state["current_loop"] -= 1
|
|
with col3:
|
|
# 下拉列表显示所有 Loop
|
|
st.session_state["current_loop"] = st.selectbox(
|
|
"选择 Loop",
|
|
options=list(range(1, total_loops + 1)),
|
|
index=st.session_state["current_loop"] - 1, # 默认选中当前 Loop
|
|
label_visibility="collapsed", # 隐藏标签
|
|
)
|
|
with col4:
|
|
if st.button("\>") and st.session_state["current_loop"] < total_loops: # 下一页
|
|
st.session_state["current_loop"] += 1
|
|
with col5:
|
|
if st.button("\>|"): # 最后一页
|
|
st.session_state["current_loop"] = total_loops
|
|
|
|
# 获取当前 Loop
|
|
current_loop = st.session_state["current_loop"]
|
|
|
|
# 渲染当前 Loop 数据
|
|
loop_id = sorted_loop_ids[current_loop - 1]
|
|
progress_text = st.empty()
|
|
progress_text.text(f"正在处理 Loop {loop_id}...")
|
|
progress_bar.progress(current_loop / total_loops, text=f"Loop :green[**{current_loop}**] / {total_loops}")
|
|
|
|
# 渲染 Loop Header
|
|
loop_anchor = f"Loop_{loop_id}"
|
|
if loop_anchor not in tlist:
|
|
tlist.append(loop_anchor)
|
|
st.header(loop_anchor, anchor=loop_anchor, divider="blue")
|
|
|
|
# 渲染当前 Loop 的所有数据
|
|
loop_data = loop_groups[loop_id]
|
|
for d in loop_data:
|
|
tag = d["tag"]
|
|
obj = d["obj"]
|
|
_, func_name = extract_loopid_func_name(tag)
|
|
evo_id = extract_evoid(tag)
|
|
|
|
func_anchor = f"loop_{loop_id}.{func_name}"
|
|
if func_anchor not in tlist:
|
|
tlist.append(func_anchor)
|
|
st.header(f"in *{func_name}*", anchor=func_anchor, divider="green")
|
|
|
|
evo_anchor = f"loop_{loop_id}.evo_step_{evo_id}"
|
|
if evo_id and evo_anchor not in tlist:
|
|
tlist.append(evo_anchor)
|
|
st.subheader(f"evo_step_{evo_id}", anchor=evo_anchor, divider="orange")
|
|
|
|
# 根据 tag 渲染内容
|
|
if "debug_exp_gen" in tag:
|
|
with st.expander(
|
|
f"Exp in :violet[**{obj.experiment_workspace.workspace_path}**]", expanded=False, icon="🧩"
|
|
):
|
|
st.write(obj)
|
|
elif "debug_tpl" in tag:
|
|
uri = obj["uri"]
|
|
tpl = obj["template"]
|
|
cxt = obj["context"]
|
|
rd = obj["rendered"]
|
|
with st.expander(highlight_prompts_uri(uri), expanded=False, icon="⚙️"):
|
|
t1, t2, t3 = st.tabs([":green[**Rendered**]", ":blue[**Template**]", ":orange[**Context**]"])
|
|
with t1:
|
|
show_text(rd)
|
|
with t2:
|
|
show_text(tpl, lang="django")
|
|
with t3:
|
|
st.json(cxt)
|
|
elif "debug_llm" in tag:
|
|
system = obj.get("system", None)
|
|
user = obj["user"]
|
|
resp = obj["resp"]
|
|
with st.expander(f"**LLM**", expanded=False, icon="🤖"):
|
|
t1, t2, t3 = st.tabs([":green[**Response**]", ":blue[**User**]", ":orange[**System**]"])
|
|
with t1:
|
|
try:
|
|
rdict = json.loads(resp)
|
|
if "code" in rdict:
|
|
code = rdict["code"]
|
|
st.markdown(":red[**Code in response dict:**]")
|
|
st.code(code, language="python", wrap_lines=True, line_numbers=True)
|
|
rdict.pop("code")
|
|
elif "spec" in rdict:
|
|
spec = rdict["spec"]
|
|
st.markdown(":red[**Spec in response dict:**]")
|
|
st.markdown(spec)
|
|
rdict.pop("spec")
|
|
else:
|
|
# show model codes
|
|
showed_keys = []
|
|
for k, v in rdict.items():
|
|
if k.startswith("model_") and k.endswith(".py"):
|
|
st.markdown(f":red[**{k}**]")
|
|
st.code(v, language="python", wrap_lines=True, line_numbers=True)
|
|
showed_keys.append(k)
|
|
for k in showed_keys:
|
|
rdict.pop(k)
|
|
st.write(":red[**Other parts (except for the code or spec) in response dict:**]")
|
|
st.json(rdict)
|
|
except:
|
|
st.json(resp)
|
|
with t2:
|
|
show_text(user)
|
|
with t3:
|
|
show_text(system or "No system prompt available")
|
|
|
|
progress_text.text("当前 Loop 数据处理完成!")
|
|
|
|
# Sidebar TOC
|
|
with st.sidebar:
|
|
toc = "\n".join([f"- [{t}](#{t})" if t.startswith("L") else f" - [{t.split('.')[1]}](#{t})" for t in tlist])
|
|
st.markdown(toc, unsafe_allow_html=True)
|