lxylxy123321 21 цаг өмнө
parent
commit
c7a0444164

+ 6 - 1
backend/app/engines/text_engine.py

@@ -334,7 +334,7 @@ class TextEngine(BaseEngine):
                 fp16=True,
                 report_to="none",
                 remove_unused_columns=False,
-                dataloader_num_workers=4,
+                dataloader_num_workers=0,
                 dataloader_pin_memory=False,
                 max_length=max_seq_length,
                 max_prompt_length=max_seq_length // 2,
@@ -625,6 +625,11 @@ class TextEngine(BaseEngine):
                             "chosen": str(chosen),
                             "rejected": str(rejected),
                         })
+        if not data:
+            raise ValueError(
+                "DPO dataset is empty after parsing. "
+                "Check that each record contains non-empty prompt/chosen/rejected fields."
+            )
         return HFDataset.from_list(data)
 
 

+ 25 - 0
backend/app/preprocessors/__init__.py

@@ -116,6 +116,25 @@ def apply_dpo_template(item: dict) -> dict:
     prompt = str(prompt) if prompt is not None else ""
     chosen = str(chosen) if chosen is not None else ""
     rejected = str(rejected) if rejected is not None else ""
+    # 防御列表型字段(messages/sharegpt 残留):拼接为单字符串
+    if isinstance(prompt, list):
+        prompt = "\n".join(
+            str(x.get("content", x)) if isinstance(x, dict) else str(x)
+            for x in prompt
+            if x is not None
+        )
+    if isinstance(chosen, list):
+        chosen = "\n".join(
+            str(x.get("content", x)) if isinstance(x, dict) else str(x)
+            for x in chosen
+            if x is not None
+        )
+    if isinstance(rejected, list):
+        rejected = "\n".join(
+            str(x.get("content", x)) if isinstance(x, dict) else str(x)
+            for x in rejected
+            if x is not None
+        )
     return {"prompt": prompt, "chosen": chosen, "rejected": rejected}
 
 
@@ -201,6 +220,12 @@ def preprocess_file(
     for item in raw_data:
         try:
             result = apply_fn(item)
+            # DPO/偏好类任务需要同时保留 prompt/chosen/rejected,
+            # 仅按 prompt 过滤会把合法偏好样本误删,最终导致空 batch 进入 collator 报错。
+            if "chosen" in result or "rejected" in result:
+                if result.get("prompt") and (result.get("chosen") or result.get("rejected")):
+                    processed.append(result)
+                continue
             if result.get("prompt"):
                 processed.append(result)
         except Exception: