FlagOS 赛道三 技术方案提交 - 21064团队 - #234
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a complete data annotation solution for the FlagOS Open Computing Global Challenge, featuring task-specific routing, dynamic example selection, deterministic tool fallback, and robust retry mechanisms. The code review identified several critical and high-severity issues in method.py. Specifically, using non-greedy regular expressions to parse input_prompt in datasets 5 and 6 causes severe text truncation when inputs contain multiple paragraphs; this can be resolved by storing the original text in a global variable during build_prompt. Additionally, dataset 7's example retrieval fails when outputs are strings rather than lists, dataset 8 lacks markdown code block stripping, and the minimum absolute difference calculation suffers from O(N^2) complexity, which can be optimized to O(N log N) via sorting. Finally, instantiating the OpenAI client on every call should be avoided in favor of a singleton pattern.
| if _TASK_TYPE == 'sentiment': | ||
| m = re.search(r'Text to Annotate\n(.+?)\n\n', input_prompt, re.DOTALL) | ||
| if not m: | ||
| return "Not sad" | ||
| input_text = m.group(1).strip() |
There was a problem hiding this comment.
在数据集 5 中,使用正则表达式 re.search(r'Text to Annotate\n(.+?)\n\n', input_prompt, re.DOTALL) 来提取待标注文本存在严重的正确性漏洞。\n\n因为 .+? 是非贪婪匹配,如果待标注文本 text2annotate 自身包含换行段落(即含有 \n\n),该正则会在第一个空行处提前停止匹配,导致后续的所有段落内容被完全截断丢弃!这在超长上下文(Long-Context)场景下是非常致命的。\n\n建议直接使用我们在 build_prompt 中保存的全局变量 _ANNOTATE_INPUT,既安全又高效。
# ---- 数据集 5:情感分析递进式重试 ----\n if _TASK_TYPE == 'sentiment':\n if not _ANNOTATE_INPUT:\n return "Not sad"\n input_text = _ANNOTATE_INPUT.strip()| if _TASK_TYPE == 'genre': | ||
| m = re.search(r'Text to Annotate\n(.+?)\n\n', input_prompt, re.DOTALL) | ||
| if not m: | ||
| return "N" | ||
| input_text = m.group(1).strip() |
There was a problem hiding this comment.
与数据集 5 类似,数据集 6 中使用正则解析 input_prompt 也会在待标注文本包含多段落(\n\n)时发生严重的文本截断。\n\n建议直接使用全局变量 _ANNOTATE_INPUT。
| if _TASK_TYPE == 'genre': | |
| m = re.search(r'Text to Annotate\n(.+?)\n\n', input_prompt, re.DOTALL) | |
| if not m: | |
| return "N" | |
| input_text = m.group(1).strip() | |
| # ---- 数据集 6:体裁分类递进式重试 ----\n if _TASK_TYPE == 'genre':\n if not _ANNOTATE_INPUT:\n return "N"\n input_text = _ANNOTATE_INPUT.strip() |
| def build_prompt(task_description: str, text2annotate: str) -> str: | ||
| global _CALC_MODE, _CALC_INPUT, _TASK_TYPE | ||
| desc = task_description.lower() |
There was a problem hiding this comment.
在 build_prompt 中,建议将传入的 text2annotate 保存到全局变量 _ANNOTATE_INPUT 中,以便后续在 annotate_nvidia 中直接使用,避免使用脆弱且容易导致截断的正则表达式来解析 input_prompt。
def build_prompt(task_description: str, text2annotate: str) -> str:\n global _CALC_MODE, _CALC_INPUT, _TASK_TYPE, _ANNOTATE_INPUT\n _ANNOTATE_INPUT = text2annotate\n desc = task_description.lower()| for ex in selected: | ||
| examples_str += f"# {ex['input'][:200]}... <label> {ex['output'][0]} </label>\n" | ||
| return examples_str |
There was a problem hiding this comment.
在数据集 7 的海马体检索中,直接使用 ex['output'][0] 会存在严重的 Bug。如果 ex['output'] 是一个字符串(例如 "Paris")而不是列表,ex['output'][0] 将只会获取该字符串的第一个字符(例如 "P"),从而导致输出的标签被错误地截断。\n\n应当像其他任务一样,先判断 ex['output'] 是否为列表,再进行安全的提取。
for ex in selected:\n output_val = ex['output'][0] if isinstance(ex['output'], list) else ex['output']\n examples_str += f"# {ex['input'][:200]}... <label> {output_val} </label>\n"\n return examples_str| code = resp.choices[0].message.content.strip() | ||
| code = re.sub(r'<think>.*?</think>', '', code, flags=re.DOTALL).strip() | ||
| if code and len(code) > 200: | ||
| return code |
There was a problem hiding this comment.
在数据集 8(Triton 代码生成)中,大语言模型通常会用 Markdown 代码块(如 ```python ... ```)包裹生成的代码,并伴随一些解释性文字。\n\n当前代码直接返回了 resp.choices[0].message.content,这会导致返回的字符串中包含 Markdown 标记和自然语言解释,从而无法通过后续的编译或执行测试。建议使用正则表达式提取出纯代码块内容,以提升该任务的鲁棒性。
code = resp.choices[0].message.content.strip()\n code = re.sub(r'<think>.*?</think>', '', code, flags=re.DOTALL).strip()\n code_match = re.search(r"```(?:python|triton)?\\s*(.*?)\\s*```", code, re.DOTALL)\n if code_match:\n code = code_match.group(1).strip()\n if code and len(code) > 200:\n return code| def _min_abs_diff(lst_str): | ||
| lst = ast.literal_eval(lst_str) | ||
| if len(lst) < 2: | ||
| return 0 | ||
| return min(abs(a - b) for a, b in combinations(lst, 2)) |
There was a problem hiding this comment.
在计算最小绝对差值时,使用 combinations(lst, 2) 会导致 O(N^2) 的时间复杂度。在长上下文场景下,如果输入列表 lst 较长,这会带来严重的性能瓶颈甚至导致超时。\n\n可以通过先对列表进行排序,然后计算相邻元素之间的差值,将时间复杂度优化至 O(N log N)。
def _min_abs_diff(lst_str):\n lst = ast.literal_eval(lst_str)\n if len(lst) < 2:\n return 0\n lst_sorted = sorted(lst)\n return min(lst_sorted[i] - lst_sorted[i - 1] for i in range(1, len(lst_sorted)))| def _get_client(): | ||
| return OpenAI(base_url="http://localhost:2026/v1", api_key="") |
There was a problem hiding this comment.
| # ==================== 全局状态 ==================== | ||
| _CALC_MODE = None | ||
| _CALC_INPUT = None | ||
| _TASK_TYPE = None |
There was a problem hiding this comment.
为了提高代码的可维护性,避免在多处硬编码模型路径 "/root/.cache/modelscope/hub/models/Qwen/Qwen3-4B",建议将其定义为全局常量。此外,为了彻底解决在 annotate_nvidia 中通过正则解析 input_prompt 导致的多段文本截断问题,建议在此处引入一个全局变量 _ANNOTATE_INPUT 来直接保存原始的 text2annotate。
| # ==================== 全局状态 ==================== | |
| _CALC_MODE = None | |
| _CALC_INPUT = None | |
| _TASK_TYPE = None | |
| # ==================== 全局状态与常量 ====================\n_MODEL_NAME = "/root/.cache/modelscope/hub/models/Qwen/Qwen3-4B"\n_CALC_MODE = None\n_CALC_INPUT = None\n_TASK_TYPE = None\n_ANNOTATE_INPUT = None |
| # ---- 数据集 7:海马体检索 ---- | ||
| if _TASK_TYPE == 'qa' or any(kw in desc_lower for kw in ['category', 'clue', 'jeopardy']): |
There was a problem hiding this comment.
这是一个架构设计上的重要发现:虽然您在 select_examples 中为数据集 7 和 8 设计了基于 SequenceMatcher 的动态检索机制,但由于官方评测入口 main.py 中对 examples_str 进行了全局缓存(即 if examples_str is None: examples_str = select_examples(...)),导致 select_examples 实际上只会针对第一个测试样本执行一次,后续所有样本都会直接复用第一次检索出的示例。\n\n因此,当前的动态检索在实际评测中退化为了静态检索。虽然由于 main.py 是官方评测入口无法直接修改,但了解这一限制有助于您后续优化方案(例如在第一次调用时检索出更具代表性的通用示例)。
| prompt = build_prompt(0 if attempt == 0 else min(attempt, 2)) | ||
| try: | ||
| resp = client.chat.completions.create( | ||
| model="/root/.cache/modelscope/hub/models/Qwen/Qwen3-4B", |
本PR为FlagOS开放计算全球挑战赛赛道三的技术方案及代码提交。
团队名称:21064
成员:甘孙逸
提交内容包括:
-技术报告