Skip to content

FlagOS 赛道三 技术方案提交 - 21064团队 - #234

Open
Thil1 wants to merge 1 commit into
FlagAI-Open:mainfrom
Thil1:Thil1-patch-1
Open

FlagOS 赛道三 技术方案提交 - 21064团队#234
Thil1 wants to merge 1 commit into
FlagAI-Open:mainfrom
Thil1:Thil1-patch-1

Conversation

@Thil1

@Thil1 Thil1 commented May 26, 2026

Copy link
Copy Markdown

本PR为FlagOS开放计算全球挑战赛赛道三的技术方案及代码提交。

团队名称:21064
成员:甘孙逸

提交内容包括:

  • method.py(核心方案代码)
  • README.md(项目说明)
  • requirements.txt(环境依赖)
  • run_inference.sh(模型部署脚本)
    -技术报告

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +175 to +179
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()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

在数据集 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()

Comment on lines +211 to +215
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()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

与数据集 5 类似,数据集 6 中使用正则解析 input_prompt 也会在待标注文本包含多段落(\n\n)时发生严重的文本截断。\n\n建议直接使用全局变量 _ANNOTATE_INPUT

Suggested change
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()

Comment on lines +32 to +34
def build_prompt(task_description: str, text2annotate: str) -> str:
global _CALC_MODE, _CALC_INPUT, _TASK_TYPE
desc = task_description.lower()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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()

Comment on lines +122 to +124
for ex in selected:
examples_str += f"# {ex['input'][:200]}... <label> {ex['output'][0]} </label>\n"
return examples_str

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在数据集 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

Comment on lines +275 to +278
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在数据集 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

Comment on lines +9 to +13
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))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在计算最小绝对差值时,使用 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)))

Comment on lines +23 to +24
def _get_client():
return OpenAI(base_url="http://localhost:2026/v1", api_key="")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

当前 _get_client() 函数在每次被调用时都会重新实例化一个 OpenAI 客户端。这会导致每次 API 请求都重新建立 TCP 连接,无法复用底层的连接池(Connection Pool),在高并发或多次重试时会带来显著的延迟开销,甚至可能导致端口耗尽。\n\n建议在全局初始化一个 OpenAI 客户端单例,并在 _get_client() 中直接返回该单例。

_client = OpenAI(base_url="http://localhost:2026/v1", api_key="")\n\ndef _get_client():\n    return _client

Comment on lines +26 to +29
# ==================== 全局状态 ====================
_CALC_MODE = None
_CALC_INPUT = None
_TASK_TYPE = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

为了提高代码的可维护性,避免在多处硬编码模型路径 "/root/.cache/modelscope/hub/models/Qwen/Qwen3-4B",建议将其定义为全局常量。此外,为了彻底解决在 annotate_nvidia 中通过正则解析 input_prompt 导致的多段文本截断问题,建议在此处引入一个全局变量 _ANNOTATE_INPUT 来直接保存原始的 text2annotate

Suggested change
# ==================== 全局状态 ====================
_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

Comment on lines +115 to +116
# ---- 数据集 7:海马体检索 ----
if _TASK_TYPE == 'qa' or any(kw in desc_lower for kw in ['category', 'clue', 'jeopardy']):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这是一个架构设计上的重要发现:虽然您在 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",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

使用前面定义的全局常量 _MODEL_NAME 代替硬编码的路径字符串。同样的修改也建议应用到第 236、253、271 和 288 行。

Suggested change
model="/root/.cache/modelscope/hub/models/Qwen/Qwen3-4B",
model=_MODEL_NAME,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant