대규모 언어 모델(LLM)의 기술적 개요
대규모 언어 모델(LLM)은 방대한 파라미터와 연산 능력을 갖춘 머신러닝 아키텍처를 의미합니다. 주로 심층 신경망(Deep Neural Networks) 기반으로 구축되며, 수십억에서 수천억 개의 파라미터를 통해 대규모 데이터를 처리하고 다양한 자연어 처리 및 코드 생성 작업에서 뛰어난 성능을 발휘합니다. 주요 특징으로는 거대한 모델 규모, 멀티모달 처리 능력, 광범위한 도메인 적용성이 있으며, 그 작동 원리는 파라미터 최적화, 네트워크 토폴로지, 순전파(Forward Propagation) 및 역전파(Backpropagation) 알고리즘에 기반합니다.
현재 시장에는 ERNIE Bot(문신일언), Kimi, Doubao(더우바오), DeepSeek 등 다양한 상용 LLM이 존재합니다. 본 글에서는 "Python Turtle 모듈을 활용한 정밀한 오성홍기(五星红旗) 그래픽 구현"이라는 동일한 태스크를 부여하여, 주요 LLM들의 코드 생성 정확도와 문제 해결 접근 방식을 비교 분석합니다.
평가 태스크 설정
목표: Python의 Turtle 그래픽 라이브러리를 사용하여 오성홍기를 정확하게 묘사하는 코드 작성.
평가 환경: Python 3.x 표준 라이브러리 (Turtle)
1. ERNIE Bot (문신일언) 평가
ERNIE Bot은 검색 및 데이터 통합에 강점을 보이는 모델입니다. 하지만 복잡한 기하학적 좌표 계산이 필요한 그래픽 태스크에서는 초기 프롬프트만으로는 정확한 결과를 도출하기 어려웠습니다.
import turtle
import math
def initialize_canvas():
ws = turtle.Screen()
ws.bgcolor("#DE2910")
return ws
def create_pen():
drawer = turtle.Pen()
drawer.speed(0)
drawer.width(2)
return drawer
def render_polygon(pen, start_x, start_y, side_len, tilt_angle, fill_hex):
pen.up()
pen.goto(start_x, start_y)
pen.setheading(tilt_angle)
pen.down()
pen.color(fill_hex)
pen.begin_fill()
for _ in range(5):
pen.forward(side_len)
pen.right(144)
pen.end_fill()
def compute_vertices(cx, cy, edge, rotation):
coords = []
for idx in range(5):
rad = math.radians(rotation + idx * 144)
coords.append((cx + edge * math.cos(rad), cy + edge * math.sin(rad)))
return coords
main_edge = 150
render_polygon(create_pen(), -50, 100, main_edge, 0, "#FFDE00")
sub_edge = main_edge * 0.33
offset_dist = main_edge * 0.8
sub_configs = [
("#FFDE00", (-50 - offset_dist * 0.8, 100 + offset_dist * 0.5)),
("#FFDE00", (-50 + offset_dist * 0.8, 100 + offset_dist * 0.5)),
("#FFDE00", (-50, 100 - offset_dist)),
("#FFDE00", (-50 + offset_dist, 100 - offset_dist * 0.8))
]
pen_instance = create_pen()
for hex_color, (px, py) in sub_configs:
render_polygon(pen_instance, px, py, sub_edge, 0, hex_color)
pen_instance.hideturtle()
turtle.done()
분석: 배경색과 별의 기본 형태는 구현했으나, 오성홍기의 공식 규격에 맞는 별의 배치와 비율, 회전 각도가 전혀 반영되지 않았습니다.
2. Kimi 평가 (초기 프롬프트)
Kimi는 코드 구조화와 함수 분할에서 안정적인 모습을 보여주었습니다. 하지만 작은 별들이 큰 별을 향하도록 회전해야 한다는 기하학적 제약 조건을 누락했습니다.
import turtle
def setup_workspace():
canvas = turtle.Screen()
canvas.bgcolor("white")
return canvas
def get_drawer():
t = turtle.Turtle()
t.speed(0)
t.penup()
return t
def paint_base_rect(drawer):
drawer.goto(-300, 200)
drawer.pendown()
drawer.color("#DE2910")
drawer.begin_fill()
for _ in range(2):
drawer.forward(600)
drawer.right(90)
drawer.forward(400)
drawer.right(90)
drawer.end_fill()
drawer.penup()
def paint_star_shape(drawer, pos, scale):
drawer.goto(pos)
drawer.setheading(-72)
drawer.pendown()
drawer.color("#FFDE00")
drawer.begin_fill()
for _ in range(5):
drawer.forward(scale)
drawer.right(144)
drawer.end_fill()
drawer.penup()
def execute_drawing():
ws = setup_workspace()
pen = get_drawer()
paint_base_rect(pen)
paint_star_shape(pen, (-200, 120), 90)
minor_stars = [
(-120, 160, 35),
(-90, 110, 35),
(-90, 50, 35),
(-120, 0, 35)
]
for x, y, s in minor_stars:
paint_star_shape(pen, (x, y), s)
pen.hideturtle()
ws.mainloop()
execute_drawing()
분석: 전체적인 레이아웃과 색상은 올바르게 적용되었으나, 4개의 작은 별이 큰 별의 중심을 향하도록 회전하지 않아 규격에 부합하지 않습니다.
3. Doubao (더우바오) 평가
Doubao는 수학적 비율과 각도 계산을 시도했으나, Turtle의 렌더링 특성(예: 펜 굵기와 채우기 경계선)을 완벽히 통제하지 못해 시각적 결함이 발생했습니다.
import turtle
import math
WIDTH, HEIGHT = 900, 600
R_MAIN = HEIGHT * 0.15
R_SUB = HEIGHT * 0.05
def draw_bg(pen, w, h, color):
pen.penup()
pen.goto(-w/2, h/2)
pen.pendown()
pen.fillcolor(color)
pen.begin_fill()
for _ in range(2):
pen.forward(w)
pen.right(90)
pen.forward(h)
pen.right(90)
pen.end_fill()
def draw_star_geom(pen, cx, cy, r, deg):
pen.penup()
pen.goto(cx, cy)
pen.setheading(deg - 90)
pen.forward(r)
pen.setheading(deg)
pen.pendown()
pen.pensize(1)
pen.fillcolor("#FFDE00")
pen.begin_fill()
edge = 2 * r * math.sin(math.radians(36))
for _ in range(5):
pen.forward(edge)
pen.right(144)
pen.end_fill()
def main_loop():
scr = turtle.Screen()
t = turtle.Turtle()
t.speed(0)
t.hideturtle()
draw_bg(t, WIDTH, HEIGHT, "#DE2910")
cx_main = -WIDTH/2 + WIDTH * 0.25
cy_main = HEIGHT/2 - HEIGHT * 0.25
draw_star_geom(t, cx_main, cy_main, R_MAIN, 0)
grid_offsets = [(2, 1), (3, 2), (3, 4), (2, 5)]
angles = []
for gx, gy in grid_offsets:
dx = gx - 1
dy = gy - 1
ang = 90 - math.degrees(math.atan2(dy, dx)) if dx != 0 else 90
angles.append(ang)
for i, (gx, gy) in enumerate(grid_offsets):
cx_sub = -WIDTH/2 + WIDTH * (0.25 + gx * 0.05)
cy_sub = HEIGHT/2 - HEIGHT * (0.25 + gy * 0.05)
draw_star_geom(t, cx_sub, cy_sub, R_SUB, angles[i])
scr.mainloop()
if __name__ == "__main__":
main_loop()
분석: 별의 위치와 회전 각도는 수학적으로 근사하게 계산되었으나, `pensize` 및 채우기 로직의 한계로 인해 별의 테두리에 불필요한 윤곽선이 나타나는 렌더링 아티팩트가 발생했습니다.
프롬프트 엔지니어링을 통한 결과 최적화
상기 평가에서 알 수 있듯이, LLM에 모호하거나 간략한 지시만 내릴 경우 기하학적 정확도와 렌더링 품질을 보장할 수 없습니다. 이를 해결하기 위해 다음과 같은 프롬프트 최적화 기법이 필요합니다.
- 명확한 제약 조건 및 수치 명시: 캔버스 해상도, 색상 HEX 코드, 객체 간의 상대적 비율 등 구체적인 수치를 프롬프트에 포함해야 합니다.
- 도메인 특화 로직 지시: "작은 별의 한 꼭짓점이 큰 별의 중심을 향해야 함"과 같은 기하학적 규칙을 명시적으로 설명하여 모델의 추론 오류를 방지해야 합니다.
- 렌더링 아티팩트 방지 지시: Turtle 그래픽의 특성상 윤곽선 제거를 위한 색상 동일화(`pencolor`와 `fillcolor` 일치) 등의 세부 구현 방식을 안내해야 합니다.
최적화된 프롬프트 적용 결과 (Kimi)
최적화된 프롬프트: "Python Turtle을 사용하여 오성홍기를 그려주세요. 캔버스 해상도는 정확히 480x320으로 설정하고, 배경색과 별의 테두리 색상을 동일하게 하여 윤곽선을 제거하세요. 4개의 작은 별은 기하학적으로 큰 별의 중심을 향하도록 회전 각도를 정확히 계산하여 적용해야 합니다."
import turtle
import math
CANVAS_W, CANVAS_H = 480, 320
COLOR_BG = "#DE2910"
COLOR_STAR = "#FFDE00"
def init_screen():
scr = turtle.Screen()
scr.setup(CANVAS_W, CANVAS_H)
scr.bgcolor("white")
return scr
def create_renderer():
r = turtle.Turtle()
r.speed(0)
r.hideturtle()
r.penup()
return r
def render_flag_base(renderer):
renderer.goto(-CANVAS_W / 2, CANVAS_H / 2)
renderer.pendown()
renderer.color(COLOR_BG)
renderer.begin_fill()
for _ in range(2):
renderer.forward(CANVAS_W)
renderer.right(90)
renderer.forward(CANVAS_H)
renderer.right(90)
renderer.end_fill()
renderer.penup()
def render_star(renderer, center_x, center_y, radius, point_to_x=None, point_to_y=None):
if point_to_x is not None and point_to_y is not None:
dx = point_to_x - center_x
dy = point_to_y - center_y
angle_rad = math.atan2(dy, dx)
angle_deg = math.degrees(angle_rad) - 18
else:
angle_deg = 90
renderer.penup()
renderer.goto(center_x, center_y)
renderer.setheading(angle_deg)
renderer.forward(radius)
renderer.right(162)
renderer.pendown()
renderer.color(COLOR_STAR)
renderer.begin_fill()
edge_len = 2 * radius * math.sin(math.radians(36))
for _ in range(5):
renderer.forward(edge_len)
renderer.right(144)
renderer.end_fill()
renderer.penup()
def generate_flag():
screen = init_screen()
pen = create_renderer()
render_flag_base(pen)
big_cx, big_cy = -CANVAS_W * 0.3, CANVAS_H * 0.2
big_r = CANVAS_H * 0.15
render_star(pen, big_cx, big_cy, big_r)
small_centers = [
(-CANVAS_W * 0.1, CANVAS_H * 0.3),
(-CANVAS_W * 0.02, CANVAS_H * 0.15),
(-CANVAS_W * 0.02, -CANVAS_H * 0.05),
(-CANVAS_W * 0.1, -CANVAS_H * 0.2)
]
small_r = CANVAS_H * 0.05
for scx, scy in small_centers:
render_star(pen, scx, scy, small_r, point_to_x=big_cx, point_to_y=big_cy)
screen.mainloop()
if __name__ == "__main__":
generate_flag()
최적화된 프롬프트를 적용한 결과, 해상도 제약 조건이 정확히 반영되었으며, `math.atan2`를 활용한 동적 각도 계산과 `pencolor` 및 `fillcolor` 통일을 통한 렌더링 아티팩트 제거가 성공적으로 이루어져 규격에 부합하는 고품질의 그래픽 출력을 얻을 수 있었습니다.