2026-11 · 작업 노트2026-11 · Project note

오독 생성기The Misreading Generator

문장을 가공 없이 이미지 모델에 건네고 기계의 오독을 작품으로 삼은 파이프라인. 닷새 동안의 개발 기록 포함.

A pipeline that handed sentences to an image model unaltered and kept the machine’s misreadings as works, with a five-day development log.

오해는 소통의 실패가 아니라 소통의 조건이다. 사람과 사람 사이에는 늘 이해의 차이가 있고, 그 차이에서 오해가 생긴다. AI도 사람이 만든 도구라서 이 오해를 물려받았다. 사람이 진심으로 건넨 말을 기계가 잘못 알아들었을 때 나오는 이미지, 그 간극을 작품으로 삼고 싶었다.

질문

사람이 진심으로 건넨 말을 기계는 어떻게 잘못 알아듣는가. 그리고 그 오독은 작품이 될 수 있는가.

원칙은 하나였다. 오독을 사람이 설계하지 않는다. 나는 문장만 고르고, 무엇을 그릴지는 이미지 모델이 정한다.

방법

방법문장을 만드는 법기대한 오독
진심 문장관계와 감정(예: "늦게 사과하는 사람", "그리움")을 씨앗으로 사람이 실제로 할 법한 한 줄을 짓는다. 그림에 관한 묘사는 넣지 않는다.기계가 알아서 해석한다
관용구·은유같은 방식이되, 글자 그대로 그리기 쉬운 영어 관용구로 짓는다.숨은 뜻이 글자 뜻으로
언어유희골라 둔 관용구 서른 개 중 하나를 그대로 넣는다. "You broke my heart.", "He's an old flame of mine."숨은 뜻이 글자 뜻으로
동어반복거트루드 스타인식 문장. "A rose is a rose is a rose."같은 것이 끝없이 자기 자신이 되는 중첩
중의성두 갈래로 읽히는 문장. "Time flies like an arrow; fruit flies like a banana."두 해석이 한 화면에서 충돌

이미지 모델은 한국어를 거의 읽지 못한다. 오독이 아예 일어나지 않으므로, 오독을 노리는 문장은 모두 영어로 정했다.

문장 뒤에는 해석을 건드리지 않는 짧은 꼬리만 붙였다.

  • 물리화: 문장 속 동사를 상징이나 아이콘이 아니라 실제로 일어나는 물리적 사건으로 그리게 했다. 처음에는 "부수다" 같은 격한 동사만 사건이 되고 "묻다·기다리다·거리를 두다" 같은 조용한 동사는 문장(紋章)처럼 납작해졌다. 그래서 조용한 동사까지 사건으로 그리도록 고쳤다.
  • 동어반복: 자기 안에 자기가 들어 있는 무한 반복(드로스테 효과, 프랙탈)을 화면의 주제로 삼게 했다.
  • 중의성: 두 해석 중 하나를 고르지 말고 이중노출로 함께 그리게 했다.
  • 공통으로 전시 품질, 가장자리까지 채운 구도, 글자와 서명이 없는 화면을 요구했다.

양식은 인상파 유화, 수묵화, 목탄, 리소그래프, 시아노타입 등 열네 가지 가운데 하나를 매번 무작위로 골랐다. 양식은 오독을 덮지 않는 선에서만 입혔다.

  • 생성은 ComfyUI에서 했다. 모델은 작품마다 FLUX.1-dev, FLUX.2 Klein 9B, Z-Image Turbo를 돌려 썼다. Z-Image는 문장을 화면에 글자로 그대로 써 넣는 경향이 있어서, 오독을 노리는 방법에서는 뺐다.
  • 4배로 키운 뒤 전시용(50 × 50cm, 50 × 70.7cm, 200dpi)과 도록용(10.5 × 10.5cm, 10.5 × 14.8cm, 300dpi) 규격에 맞춰 CMYK로 변환했다.
  • 작품마다 문장, 방법, 양식, 모델, seed, 프롬프트 전문을 함께 기록했다.

작가 스테이트먼트, 프롬프트, 문장 씨앗 목록을 문서 하나에 모아 두고, 생성기는 그 문서를 읽어 쓰도록 분리했다. 씨앗 문장 한 줄을 더하면 다음 실행부터 바로 반영되었다.

시도와 실패

생성기는 개인 작업용 자동화 환경 안에서 Python 스크립트 하나로 시작했다. 5일 동안 다섯 번 크게 고쳤다.

날짜바꾼 것이유
7/10자동 실행 시작. 언어 모델이 "오독을 설계한" 프롬프트를 만들어 이미지 모델에 넘기는 방식처음 가설
7/11설계 단계를 지우고 RAW 방식 하나로 통일. 컨셉·씨앗·양식을 코드에서 문서 하나로 분리하고, 문서가 없으면 내장 기본값으로 돌아가는 로더를 붙임오독의 주체가 언어 모델이 아니라 이미지 모델이어야 했다
7/11워크플로를 "모델별 앞단 + 공통 뒷단"으로 재설계. FLUX.1-dev, FLUX.2 Klein, Z-Image를 작품마다 돌림. 사용한 모델 이름을 기록에 자동으로 적음모델이 바뀌어도 확대·CMYK 변환 단계를 그대로 쓰기 위해
7/11관용구·언어유희 방법 추가. 언어유희는 언어 모델을 거치지 않고 씨앗 문장을 그대로 넣음오독이 일어나는 문장을 더 통제하기 위해
7/13동어반복·중의성 추가. 물리화 가드를 양식 지시보다 앞에 두고, 조용한 동사까지 사건으로 그리게 보강. 네 방법 모두에서 Z-Image 제외가드가 뒤에 있으면 양식에 묻혔고, Z-Image는 문장을 자막처럼 그려 넣었다

가장 큰 실패는 두 가지였다. 첫째, Z-Image는 "글자 없음"을 지시해도 넣은 문장을 화면에 그대로 써 넣었다. 기계가 문장을 잘못 읽은 것이 아니라 아예 읽지 않고 받아 적은 셈이라, 오독이 일어나지 않았다. 둘째, "묻다" 같은 조용한 동사는 사건이 되지 못하고 도끼 두 자루가 엇갈린 문장(紋章)처럼 납작해졌다.

실패한 출력 다섯 점
왼쪽 넷은 Z-Image가 문장을 글자로 찍어 버린 출력이다. 맨 오른쪽 〈…bury the hatchet〉(화해하다)은 묻는 행위 대신 엇갈린 도끼 아이콘이 되었다. 이 두 실패로 Z-Image를 오독 방법에서 빼고, 물리화 가드를 양식 지시보다 앞에 두었다.

워크플로는 7월 11일에 "모델마다 다른 앞단 + 모두 같이 쓰는 뒷단"으로 다시 짰다. 모델을 바꿔도 확대·크기 맞춤·CMYK 변환은 그대로 쓰기 위해서다.

generate_exhibition.py — 워크플로 조립 (2026-07-11)
def build_workflow(model_key, prompt, seed, base_wh, target_wh, prefix):
    tw, th = target_wh
    head = MODELS[model_key]["builder"](prompt, seed, base_wh)   # 모델마다 다른 앞단
    tail = {                                                      # 모든 모델이 같이 쓰는 뒷단
        "up_model": {"class_type": "UpscaleModelLoader",
                     "inputs": {"model_name": "4x-UltraSharp.pth"}},
        "upscale":  {"class_type": "ImageUpscaleWithModel",
                     "inputs": {"upscale_model": ["up_model", 0], "image": ["decode", 0]}},
        "resize":   {"class_type": "ImageScale",
                     "inputs": {"image": ["upscale", 0], "upscale_method": "lanczos",
                                "width": tw, "height": th, "crop": "center"}},
        "save":     {"class_type": "SaveImage",
                     "inputs": {"images": ["resize", 0], "filename_prefix": prefix}},
    }
    return {**head, **tail}

글자가 남는 문제는 부정 프롬프트와도 얽혀 있었다. FLUX 계열은 cfg 1에서 부정 조건을 무시해서, "글자 없음"을 지시해도 서명과 글자가 남았다. cfg가 1보다 큰 모델에서만 부정 조건을 쓰고, 나머지는 조건을 0으로 비우는 노드를 넣었다.

generate_exhibition.py — 부정 조건 처리 (2026-07-11)
if distilled:
    # cfg 1에서는 부정 조건이 무시된다 → 조건을 0으로 비운다
    common["neg"] = {"class_type": "ConditioningZeroOut",
                     "inputs": {"conditioning": ["pos", 0]}}
else:
    # cfg가 1보다 클 때만 부정 조건이 실제로 작동한다 → 서명·글씨 억제
    common["neg"] = {"class_type": "CLIPTextEncode",
                     "inputs": {"text": NEG_PROMPT, "clip": ["clip", 0]}}

결정

7월 10~14일 생성기 출력 56점
7월 10일부터 14일까지 NAS에 보관된 출력 전체. 〈아직 너한테 할 말을 못 찾겠어〉(1행 여섯째), 〈안쪽의 계절〉(1행 아홉째), 〈A mirror is a mirror is a mirror.〉(6행 둘째)가 이 안에 있다.

예약 실행은 7월 10일부터 14일까지 마흔세 번 돌았고, NAS에는 수동 실행을 포함해 쉰여섯 점이 남았다. 방법이 기록된 서른 점 가운데 관용구·은유가 열다섯, 언어유희가 여덟, 동어반복이 다섯, 중의성이 둘이었다.

이 가운데 〈A rose is a rose is a rose〉, 〈아직 너한테 할 말을 못 찾겠어〉, 〈안쪽의 계절〉, 〈A mirror is a mirror is a mirror.〉 네 점을 골랐다.

작품마다 생성 기록이 남아 있다. 아래는 7월 10일, 아직 언어 모델이 오독을 설계하던 첫날의 기록이다.

IMG_20260710_232117.md — 생성 기록 발췌
- 생성일시: 2026-07-10 23:21:17
- 프로그램: ComfyUI + FLUX.1-dev + 4x-UltraSharp
- 판형: square · seed 1360513725
- 명령: 아직 너한테 할 말을 못 찾겠어 — I still can't find the words for you
- AI 오독: 'find the words' read literally: a person wading through mist
  to gather scattered blank paper-words, each one slipping away
  before it can be grasped
- 양식: soft impressionist oil painting, visible brushwork, muted palette
- 전시용: 3937x3937px @200dpi CMYK · 도록용: 1240x1240px @300dpi CMYK

한 점의 예. "He's an old flame of mine."(목탄·흑연 드로잉 양식, FLUX.1-dev)

'오래된 불꽃'은 옛 연인을 뜻하는 관용구다. 그러나 기계는 은유를 모른다. 문장을 글자 그대로 읽어 관용의 온기를 실제로 타오르는 늙은 불로 바꾼다. 연인이 있어야 할 자리에 사그라드는 불이 놓인다.

〈안쪽의 계절〉은 석 달 뒤 다시 골랐다. 10월 30일 밤, 한국미디어아트협회 국제전에 낼 작품을 찾으려고 서른아홉 개 주제를 밤새 돌리는 일괄 생성을 걸었다. 그런데 작업용 PC가 1시간 12분 만에 예기치 않게 꺼져 26장에서 멈췄다. 마감이 지나 다시 돌리지 않았다. 그 대신 7월의 오독 생성기에서 나온 〈안쪽의 계절〉을 냈다. "엄마, 나 여기 있는데 왜 안 봐줘요?"라는 문장에서 나왔지만, 그 말을 한 사람은 화면 어디에도 없는 이미지다.

10월 30일 야간 일괄 생성 비교표
10월 30일 밤 일괄 생성이 멈추기 전까지 만든 26장의 비교표 원본. 같은 주제를 여러 시드로 비교해 고르려던 것이다.

남은 질문

생성기는 2026년 7월 14일을 마지막으로 돌리지 않았고, 11월에 정리했다. 지금은 다른 방식으로 작업하지만, 문장을 고르는 사람과 그림을 정하는 기계 사이의 간격은 계속 남는 질문이다. 오독이 우연이 아니라 방법이 될 수 있다면, 그 방법은 어디까지 사람의 몫인가.

Misunderstanding is not a failure of communication but one of its conditions. There is always a gap in understanding between people, and misunderstanding grows out of it. AI, as a human-made tool, inherits that gap. I wanted to make work from the image that appears when a machine mishears something a person meant sincerely.

Question

How does a machine mishear what a person sincerely says, and can that misreading become a work?

There was one rule: I do not design the misreading. I choose the sentence; the image model decides what to draw.

Method

MethodHow the sentence is madeThe misreading it invites
Heartfelt lineSeeded with a relationship and an emotion (“someone apologising years too late”, “longing”), write one line a person might actually say. No visual description.Left entirely to the machine
Idiom and metaphorThe same, but built on an English idiom that is easy to draw literally.Figurative meaning taken literally
WordplayOne of thirty chosen idioms, used as is: “You broke my heart.”, “He's an old flame of mine.”Figurative meaning taken literally
TautologyLines in the manner of Gertrude Stein: “A rose is a rose is a rose.”The same thing endlessly becoming itself
AmbiguityLines that parse two ways: “Time flies like an arrow; fruit flies like a banana.”Two readings colliding in one image

Image models barely read Korean, so no misreading happens at all. Every sentence aimed at misreading was therefore in English.

Only a short tail that leaves interpretation alone was added after each sentence.

  • Make it physical: draw the verbs as physical events actually taking place, not as symbols or icons. At first only violent verbs such as “break” became events, while quiet ones — bury, wait, keep at a distance — flattened into emblems, so the guard was revised to cover them too.
  • Tautology: make endless self-nesting (the Droste effect, fractals) the subject.
  • Ambiguity: do not choose a reading; show both at once as a double exposure.
  • In every case: gallery quality, composition bleeding to the edges, no lettering or signatures.

One of fourteen styles — impressionist oil, ink wash, charcoal, risograph, cyanotype and others — was chosen at random each time, and applied only as far as it did not cover the misreading.

  • Images were generated in ComfyUI, rotating FLUX.1-dev, FLUX.2 Klein 9B and Z-Image Turbo from work to work. Z-Image tended to write the sentence into the picture as text, so it was dropped from the methods that aimed at misreading.
  • Each image was upscaled four times and converted to CMYK at exhibition sizes (50 × 50 cm, 50 × 70.7 cm, 200 dpi) and catalogue sizes (10.5 × 10.5 cm, 10.5 × 14.8 cm, 300 dpi).
  • For every work, the sentence, method, style, model, seed and full prompt were recorded.

The artist statement, prompts and seed lists lived in a single document that the generator read at run time. Adding one seed sentence changed the very next run.

Attempts and failures

The generator began as a single Python script inside my personal automation setup. It was rebuilt five times in five days.

DateChangeWhy
10 JulScheduled runs begin. A language model writes a prompt that "designs" the misreading and passes it to the image modelThe first hypothesis
11 JulThe design step is removed in favour of one RAW path. Concept, seeds and styles move from the code into a single document, with a loader that falls back to built-in defaultsThe image model, not the language model, had to be the one misreading
11 JulThe workflow is rebuilt as "model-specific front end + shared back end", rotating FLUX.1-dev, FLUX.2 Klein and Z-Image per work and recording the model actually usedSo upscaling and CMYK conversion survive any model change
11 JulIdiom and wordplay methods added; wordplay seeds go straight to the image modelTo control which sentences trigger misreading
13 JulTautology and ambiguity added. The physicalising guard moves ahead of the style instruction and is extended to quiet verbs. Z-Image is dropped from all four methodsPlaced after the style, the guard was ignored; Z-Image wrote the sentence into the picture like a caption

Two failures mattered most. First, Z-Image wrote the sentence into the picture even when told not to: rather than misreading the sentence, it simply transcribed it, so no misreading happened at all. Second, quiet verbs such as "bury" never became events and flattened into emblems, like two crossed axes.

Five failed outputs
The four on the left are Z-Image outputs that printed the sentence as text. On the far right, …bury the hatchet became a crossed-axes icon instead of an act of burying. These two failures led to dropping Z-Image from the misreading methods and moving the physicalising guard ahead of the style instruction.

On 11 July the workflow was rebuilt as a model-specific front end with a back end shared by every model, so upscaling, resizing and CMYK conversion survive any model change.

generate_exhibition.py — workflow assembly (2026-07-11)
def build_workflow(model_key, prompt, seed, base_wh, target_wh, prefix):
    tw, th = target_wh
    head = MODELS[model_key]["builder"](prompt, seed, base_wh)   # model-specific front end
    tail = {                                                      # back end shared by every model
        "up_model": {"class_type": "UpscaleModelLoader",
                     "inputs": {"model_name": "4x-UltraSharp.pth"}},
        "upscale":  {"class_type": "ImageUpscaleWithModel",
                     "inputs": {"upscale_model": ["up_model", 0], "image": ["decode", 0]}},
        "resize":   {"class_type": "ImageScale",
                     "inputs": {"image": ["upscale", 0], "upscale_method": "lanczos",
                                "width": tw, "height": th, "crop": "center"}},
        "save":     {"class_type": "SaveImage",
                     "inputs": {"images": ["resize", 0], "filename_prefix": prefix}},
    }
    return {**head, **tail}

The lettering problem was tied to the negative prompt. FLUX models ignore negative conditioning at cfg 1, so "no text" still left signatures and letters. Negative conditioning is used only for models running above cfg 1; for the rest the conditioning is zeroed out.

generate_exhibition.py — negative conditioning (2026-07-11)
if distilled:
    # negative conditioning is ignored at cfg 1 -> zero it out
    common["neg"] = {"class_type": "ConditioningZeroOut",
                     "inputs": {"conditioning": ["pos", 0]}}
else:
    # negatives only work above cfg 1 -> suppress signatures and text
    common["neg"] = {"class_type": "CLIPTextEncode",
                     "inputs": {"text": NEG_PROMPT, "clip": ["clip", 0]}}

Decision

All 56 outputs, 10–14 July
Every output archived on the NAS from 10 to 14 July. I Still Can't Find the Words for You (row 1, sixth), The Season Within (row 1, ninth) and A mirror is a mirror is a mirror. (row 6, second) are among them.

Scheduled runs fired forty-three times between 10 and 14 July, and fifty-six outputs, including manual runs, remain on the NAS. Of the thirty whose method was logged, fifteen were idiom and metaphor, eight wordplay, five tautology and two ambiguity.

From these I chose four: A rose is a rose is a rose, I Still Can't Find the Words for You, The Season Within and A mirror is a mirror is a mirror.

Every work left a generation record. This one is from 10 July, the first day, when a language model still designed the misreading.

IMG_20260710_232117.md — excerpt of a generation record
- Generated: 2026-07-10 23:21:17
- Software: ComfyUI + FLUX.1-dev + 4x-UltraSharp
- Orientation: square · seed 1360513725
- Command: 아직 너한테 할 말을 못 찾겠어 — I still can't find the words for you
- AI misreading: 'find the words' read literally: a person wading through mist
  to gather scattered blank paper-words, each one slipping away
  before it can be grasped
- Style: soft impressionist oil painting, visible brushwork, muted palette
- Exhibition: 3937x3937px @200dpi CMYK · Catalogue: 1240x1240px @300dpi CMYK

One example: “He's an old flame of mine.” (charcoal and graphite, FLUX.1-dev)

“An old flame” is an idiom for a former lover. But the machine knows no metaphor. Reading the sentence literally, it turns the idiom’s warmth into an actual aging fire. Where the beloved should stand, a dying flame smoulders instead.

The Season Within was chosen again three months later. On the night of 30 October I set an overnight batch running thirty-nine themes to find a work for the Korea Media Art Association's international exhibition. The workstation shut down unexpectedly after 1 hour 12 minutes, stopping at 26 images, and the deadline had passed before it could run again. Instead I submitted The Season Within from the July generator: an image born from the sentence "Mom, I'm right here, why won't you look at me?", in which the one who said it appears nowhere.

Overnight batch comparison sheet, 30 October
The original comparison sheet of the 26 images made before the overnight batch stopped. It was meant for comparing several seeds of each theme.

Open questions

The generator last ran on 14 July 2026 and was retired in November. I now work in other ways, but the gap between the person who chooses the words and the machine that decides the picture remains. If misreading can be a method rather than an accident, how much of that method belongs to the person?

관련 작품Related works