AI 이미지 모델은 여전히 철자를 쓰지 못합니다. 그러니 요구하지 마세요.
요약
AI 이미지 생성 모델의 고질적인 문제인 텍스트 렌더링 오류와 철자 부정확성을 지적합니다. 모델에 텍스트 생성을 맡기기보다, 배경은 AI로 생성하고 글자는 코드로 직접 렌더링하여 합성하는 레이어 분리 방식을 권장합니다.
핵심 포인트
- AI 이미지 모델은 여전히 철자 및 타이포그래피 구현에 한계가 있음
- FLUX.1 등 최신 모델도 텍스트 정확도는 약 60% 수준에 불과함
- 신뢰할 수 있는 결과물을 위해 '모델은 픽셀을, 코드는 글자를' 원칙 적용
- 배경은 AI로, 텍스트는 프로그래밍 방식으로 생성 후 합성하는 워크플로우 권장
AI 이미지 모델은 여전히 철자를 쓰지 못합니다. 그러니 요구하지 마세요.
이번 주에 제 비디오 파이프라인(video pipeline)에는 이미지 하나가 필요했습니다. 짧은 설정 파일(config file)이 보이는 어두운 코드 에디터 — 제목 하나, 세 개의 헤딩(headings), 네 개의 불렛 라인(bullet lines). 간단해 보이죠?
자동화된 아트 페치(art fetch) 결과로 토성(Saturn) 사진이 돌아왔습니다. 누군가의 캡션이 구석에 박혀 있는, 실제 JWST(제임스 웹 우주 망원경)가 찍은 행성 사진 말입니다. 제 QA 게이트(QA gate)가 게시 직전 한 프레임 전에 이를 잡아냈습니다.
여기서 중요한 점은 다음과 같습니다. 해결책은 "더 나은 프롬프트(prompt)와 함께 더 나은 이미지 모델을 사용하는 것"이 _아니었다_는 점입니다. 제 앞에는 FLUX 엔드포인트(endpoint)가 바로 있었지만 사용하지 않았습니다. 만약 여러분의 파이프라인이 AI 생성 이미지 안에 글자를 넣어야 한다면, 여러분도 사용해서는 안 됩니다.
생성된 이미지 내부의 텍스트는 주사위 던지기와 같습니다
이것은 단순히 느낌(vibes)의 문제가 아닙니다. 이미지 생성 분야에서 가장 잘 문서화된 약점 중 하나입니다.
- 읽을 수 있고 철자가 정확한 텍스트를 렌더링(rendering)하는 것은 확산 모델(diffusion models)의 알려진 고질적인 과제입니다. 모델이 철자를 쓰게 만드는 데만 전념하는 전체 연구 계보(TextDiffuser, Glyph-ByT5, GlyphControl)가 존재하며, 2025년 스트레스 테스트 벤치마크(STRICT)는 철자 정확도가 "최첨단 모델에서도 여전히 만족스럽지 않다"는 것을 보여줍니다.
- 타이포그래피(typography) 측면에서 진정으로 더 나은 오픈 모델 중 하나인 FLUX.1은 짧은 텍스트에 대해 첫 시도 정확도가 약 60% 정도에 머뭅니다. "FUTURE DESIGN"이라고 적힌 잡지 표지를 요청하면, 일정 확률로 "FUTUR3 DESLGN"과 같은 결과를 얻게 됩니다.
60%는 재미있는 데모용 수치일 뿐입니다. 제품의 이름이 들어가는 그 어떤 것에서도 완전히 출시 불가능한 결함률입니다. 만약 제 비디오의 한 비트에서 CLAUDE.md라는 파일을 보여줘야 하는데 프레임에 CLUADE.rnd라고 렌더링된다면, 그 프레임은 출시될 수 없습니다. 그리고 제 비평 게이트(critic gate)는 _글자가 하나라도 엉망이면 자동으로 탈락 처리_합니다. 따라서 생성 과정을 사람이 모든 후보를 뚫어지게 쳐다보며 루프(loop)를 돌며 재시도하거나... 아니면 이 게임을 그만두어야 합니다.
해결책: 레이어를 분리하세요
이제 제가 모든 미디어 파이프라인에 적용하는 규칙은 다음과 같습니다:
모델은 픽셀(pixels)을 그리고, 코드는 글자(letters)를 그립니다.
배경, 질감, 장면, 분위기 등 장식적인 요소는 AI로 자유롭게 생성합니다. 하지만 파일 이름, 제목, 코드, UI 레이블, 가격처럼 반드시 읽혀야(read) 하는 모든 것은 폰트 파일이 모든 글리프(glyph)를 보장하는 프로그래밍 방식(programmatically)으로 렌더링합니다. 그 다음 합성(composite)합니다.
제 설정 카드(config-card) 프레임의 경우, 이미지 전체가 텍스트이기 때문에 모델을 완전히 건너뛰었습니다. 단 하나의 ffmpeg 명령어로 약 1초 만에, 비용 없이, 결정론적(deterministically)이고 완벽한 글자로 그려낼 수 있습니다:
// make-card.mjs — AI를 사용하지 않은, 완벽한 글자의 "코드 에디터" 카드
import { spawnSync } from "child_process";
import fs from "fs"; import os from "os"; import path from "path";
...
제가 시행착오를 겪으며 배운 세 가지 세부 사항은 다음과 같습니다:
text=대신textfile=을 사용하세요. 인라인drawtext이스케이프 처리(콜론, 따옴표, 퍼센트 기호 등)를 하다가 오후 시간을 통째로 날릴 수 있습니다. 줄당 하나의 UTF-8 파일을 사용하는 방식은 엠 대시(em-dash)나●같은 문자도 포함하여 문제없이 작동합니다.- 목표 프레임의 1.5~2배 크기로 렌더링하세요. 만약 이미지에 켄 번즈(Ken Burns) 효과(줌)나 다운스트림(downstream)에서의 리스케일링(rescale)이 적용된다면, 정확한 크기로 렌더링된 텍스트는 흐릿해집니다. 오버샘플링(Oversample)한 뒤 파이프라인에서 다운스케일링(downscale)되도록 하세요.
- 색상당 하나의
drawtext를 사용하세요.drawtext는 단색입니다. 하나의 필터 안에서 영리하게 처리하려고 애쓰는 대신, 색상별(제목 vs 본문)로 줄을 그룹화하세요.
ffmpeg가 그릴 수 있는 것보다 더 풍부한 레이아웃(flexbox, 그라데이션, 둥근 모서리 등)이 필요한가요? 원리는 같습니다. 도구만 더 좋을 뿐입니다: Satori(Vercel의 HTML/CSS-to-SVG 라이브러리이자 그들의 OG-image 서비스의 기반이 되는 도구)를 사용하면 글리프가 보장된 실제 레이아웃을 얻을 수 있으며, node-canvas나 Sharp를 사용하여 텍스트 레이어를 AI 배경 위에 합성할 수 있습니다. 핵심은 합성(compositing)에 있습니다: 생성된 픽셀(pixels)은 아래에(under), 결정론적인 타이포그래피(type)는 위에(over) 두는 것입니다.
일반적인 규칙 (이는 이미지 그 이상의 문제입니다)
Saturn 사건과 철자 연구는 두 가지 형태를 띤 동일한 교훈입니다:
확률론적 구성 요소(probabilistic component)가 결정론적 구성 요소(deterministic component)가 생성할 수 있는 것을 만들게 하지 마세요.
이미지 속의 텍스트는 가장 명확한 예시입니다. 폰트 파일은 영원히, 비용 없이, 오타율 0%를 유지합니다. 하지만 이 패턴은 에이전트 파이프라인(agent pipelines) 전반에서 반복됩니다.
- 모델이 산술 연산 (arithmetic)을 산문 형식으로 수행하게 두지 마세요. 계산기 (calculator)를 호출하게 만드세요.
- 모델이 당신의 테스트 명령어를 "기억"하게 두지 마세요. 매 세션마다 읽어들이는 설정 파일 (config file)에 고정하세요.
- 렌더링 (render) 시점에 "멋진 배경"을 다시 가져오게 두지 마세요. 모든 재렌더링 (re-render)이 재현 가능하도록 (reproducible) 정확한 에셋 경로 (asset path)를 고정하세요.
오직 모델만이 할 수 있는 일에만 모델을 사용하세요. 그 외의 모든 것은 코드를 작성하세요 — 철자를 정확히 쓰는 코드를 작성하세요.
저는 엄격한 QA 게이트 (QA gates)를 갖춘 자동화된 콘텐츠 파이프라인 (automated content pipelines)을 구축합니다. 모든 렌더링의 모든 프레임은 배포되기 전에 비평가 (critic)에 의해 읽힙니다. Saturn 프레임은 실재하며, 그것을 잡아낸 킬 룰 (kill rule) 또한 실재합니다. 이와 같은 현장 노트 (field notes)를 더 보고 싶다면 팔로우하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기