[Open WebUI] 스트림 청크 핸들러에서 yield 호출 횟수 절반으로 줄이기
PR #23266 - perf: single yield per line in stream chunks handler
들어가며
Open WebUI의 yield_safe_stream_chunks 함수는 스트리밍 응답의 각 라인을 처리할 때, 라인 바이트와 개행 문자(b'\n')를 별도로 yield하고 있었습니다. 이로 인해 모든 스트리밍 응답에서 async generator의 중단(suspend)과 재개(resume) 사이클이 두 배로 발생했습니다.
핵심 코드 분석
Before
# 라인 데이터와 개행을 따로 yield -> 2번의 async suspend/resume
yield b'data: {}'
yield b'\n'
# 일반 라인도 마찬가지
yield line
yield b'\n'
After
# 한 번의 yield로 통합
yield b'data: {}\n'
# 일반 라인도 통합
yield line + b'\n'
4개의 yield 지점 모두에서 동일한 패턴으로 수정되었습니다.
왜 이게 좋은가
- async generator 오버헤드 절반 감소: 각 yield마다 발생하는 코루틴 중단/재개 비용이 절반으로 줄어듭니다.
- 출력 완전 동일: 바이트 단위로 완전히 동일한 출력을 생성하므로 하위 호환성에 영향이 없습니다.
- 단순한 변경, 명확한 효과: 바이트 문자열 연결이라는 매우 저렴한 연산으로 yield 횟수를 줄입니다.
- 스트리밍 특성상 누적 효과: 긴 대화에서 수천 줄이 스트리밍되므로, 줄마다 한 번씩 아끼는 효과가 크게 누적됩니다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] JS transition을 CSS 애니메이션으로 교체하여 스트리밍 렌더링 최적화
- 현재글 : [Open WebUI] 스트림 청크 핸들러에서 yield 호출 횟수 절반으로 줄이기
- 다음글 [sglang] sgl-kernel 레거시 경로 대규모 제거: AOT에서 JIT로의 전환 완성
댓글