[Open WebUI] 스트리밍 중 동일 콘텐츠의 중복 마크다운 파싱을 캐시로 방지
PR 링크: open-webui/open-webui#22183 상태: Merged | 변경: +10 / -1
들어가며
Open WebUI의 Markdown.svelte 컴포넌트에서 parseTokens() 함수는 스트리밍 중 매 애니메이션 프레임마다 호출됩니다. 그런데 모델이 일시적으로 출력을 멈춘 경우에도, 콘텐츠 문자열이 동일한 상태에서 processResponseContent(), replaceTokens(), marked.lexer()를 반복 실행했습니다. 이 PR은 단순한 문자열 비교 캐시를 추가하여 콘텐츠가 변경되지 않았을 때 파싱을 건너뜁니다.
핵심 코드 분석
Before: 매번 무조건 파싱
const parseTokens = () => {
tokens = marked.lexer(
replaceTokens(processResponseContent(content), model?.name, $user?.name)
);
};
After: 이전 값과 비교 후 변경 시에만 파싱
let lastContent = '';
let lastParsedContent = '';
const parseTokens = () => {
if (content === lastContent) return; // 원본 콘텐츠 동일하면 즉시 반환
lastContent = content;
const processed = replaceTokens(processResponseContent(content), model?.name, $user?.name);
if (processed === lastParsedContent) return; // 처리 후 결과도 동일하면 반환
lastParsedContent = processed;
tokens = marked.lexer(processed);
};
왜 이게 좋은가
- 이중 가드: 원본
content와 처리된 문자열 두 단계에서 비교하므로,processResponseContent나replaceTokens가 같은 결과를 내는 경우도 잡아낸다. - 모델 일시 정지 시 효과적: LLM 스트리밍에서 모델이 사고(thinking) 중일 때 프레임마다 불필요한 파싱을 방지한다.
- 최소한의 코드 변경: 변수 2개와 조건문 2개만 추가하여 기존 로직에 영향을 주지 않는다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [Open WebUI] O(n²) unshift를 O(n) push+reverse로 교체하여 메시지 빌드 최적화
- 현재글 : [Open WebUI] 스트리밍 중 동일 콘텐츠의 중복 마크다운 파싱을 캐시로 방지
- 다음글 [Open WebUI] TTS 문장 파싱을 showCallOverlay 가드로 감싸 불필요한 O(n^2) 연산 제거
댓글