본문으로 건너뛰기

[Ray Data] LLM 배치 추론에서 개별 행 실패 시에도 작업을 계속하는 에러 핸들링 추가

PR 링크: ray-project/ray#59212 상태: Merged | 변경: +436 / -32

들어가며

대규모 LLM 배치 추론에서 수백만 행 중 단 하나의 잘못된 프롬프트(예: max_model_len 초과)가 전체 작업을 중단시키는 것은 심각한 문제다. vLLM은 내부적으로 복구 가능한 EngineGenerateError와 치명적인 EngineDeadError를 구분하지만, Ray Data의 LLM 프로세서는 모든 에러를 동일하게 전파하여 작업을 중단시켰다. 이 PR은 should_continue_on_error 옵션을 추가하여 복구 가능한 에러는 에러 컬럼으로 표시하고 작업을 계속하게 한다.

핵심 코드 분석

에러 행 생성 (vLLM 스테이지)

_VLLM_FATAL_ERRORS: Tuple[Type[Exception], ...] = ()
try:
    from vllm.v1.engine.exceptions import EngineDeadError
    _VLLM_FATAL_ERRORS = (EngineDeadError,)
except ImportError:
    pass

async def _generate_with_error_handling(self, row, batch_uuid):
    try:
        request, output, time_taken_llm = await self.llm.generate_async(row)
        return { ... }  # 정상 결과
    except _VLLM_FATAL_ERRORS:
        raise  # 치명적 에러는 즉시 전파
    except Exception as e:
        if not self.should_continue_on_error:
            raise
        return {"__inference_error__": str(e), ...}  # 에러 행

에러 행 바이패스 (base 스테이지)

def _postprocess(row):
    data = row[processor_data_column]
    # 에러 행은 사용자 postprocess 건너뛰기
    if data.get("__inference_error__") is not None:
        return data
    result = fn(data)
    if include_error_column:
        result["__inference_error__"] = None
    return result

사용 예시

config = vLLMEngineProcessorConfig(
    model_source="meta-llama/Meta-Llama-3.1-8B-Instruct",
    should_continue_on_error=True,
)
result = processor(ds)
successful = result.filter(lambda r: r["__inference_error__"] is None)
failed = result.filter(lambda r: r["__inference_error__"] is not None)

왜 이게 좋은가

  1. 치명적/복구 가능 에러 구분: vLLM의 EngineDeadError(엔진 프로세스 크래시)는 무조건 전파하고, 요청별 에러만 개별 처리한다. 엔진이 죽은 상태에서 계속 처리하는 것은 무의미하기 때문이다.
  2. 일관된 스키마: __inference_error__ 컬럼이 모든 출력 행에 포함되어(성공 시 None, 실패 시 에러 메시지), 다운스트림에서 filter 한 번으로 성공/실패를 분리할 수 있다.
  3. postprocess 바이패스: 에러 행은 generated_text 등 기대 필드가 없으므로 사용자 postprocess를 건너뛴다. 이차 크래시를 방지하는 방어적 설계다.
  4. 기본값 보수적: should_continue_on_error=False가 기본이므로 기존 fail-fast 동작이 유지된다. 옵트인 방식이다.

참고 자료

댓글

관련 포스트

PR Analysis 의 다른글