테이블/CSV 합성, JSON/SQL 데이터 생성, 이미지-텍스트 페어 생성, NVIDIA Nemotron 등 멀티모달 합성 데이터 생성 기법을 다룹니다.
구조화된 테이블 데이터의 합성은 텍스트 합성과는 근본적으로 다른 도전을 제시합니다. 각 컬럼 간의 상관관계, 분포 특성, 제약 조건을 모두 보존해야 하기 때문입니다.
테이블 데이터 합성에서 가장 중요한 것은 원본 데이터의 통계적 특성을 보존하는 것입니다. 단순히 각 컬럼을 독립적으로 샘플링하면 컬럼 간 상관관계가 파괴됩니다.
| 방식 | 장점 | 단점 | 적합한 상황 |
|---|---|---|---|
| GAN 기반 (CTGAN) | 복잡한 분포 학습 | 학습 불안정, 모드 붕괴 | 대규모 원본 데이터 존재 시 |
| VAE 기반 (TVAE) | 안정적 학습 | GAN 대비 낮은 충실도 | 중간 규모 데이터 |
| 가우시안 코풀라 | 빠른 생성, 해석 가능 | 비선형 관계 포착 한계 | 정규 분포에 가까운 데이터 |
| LLM 기반 | 맥락 이해, 유연성 | 높은 비용, 대규모 어려움 | 소규모, 복잡한 맥락 필요 시 |
import pandas as pd
import numpy as np
from sdv.single_table import CTGANSynthesizer
from sdv.metadata import SingleTableMetadata
def synthesize_tabular_data(
real_data: pd.DataFrame,
num_samples: int,
epochs: int = 300,
) -> pd.DataFrame:
"""CTGAN을 사용하여 테이블 데이터를 합성합니다."""
# 메타데이터 자동 감지
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_data)
# CTGAN 모델 학습
synthesizer = CTGANSynthesizer(
metadata,
epochs=epochs,
batch_size=500,
verbose=True,
)
synthesizer.fit(real_data)
# 합성 데이터 생성
synthetic_data = synthesizer.sample(num_rows=num_samples)
return synthetic_data
def validate_statistical_properties(
real: pd.DataFrame,
synthetic: pd.DataFrame,
) -> dict:
"""합성 데이터의 통계적 특성을 검증합니다."""
results = {}
for col in real.columns:
if real[col].dtype in [np.float64, np.int64]:
# 수치형: KS 검정
from scipy import stats
ks_stat, p_value = stats.ks_2samp(real[col], synthetic[col])
results[col] = {
"ks_statistic": ks_stat,
"p_value": p_value,
"mean_diff": abs(
real[col].mean() - synthetic[col].mean()
),
"std_diff": abs(
real[col].std() - synthetic[col].std()
),
}
else:
# 범주형: 분포 비교
real_dist = real[col].value_counts(normalize=True)
synth_dist = synthetic[col].value_counts(normalize=True)
results[col] = {
"distribution_match": real_dist.to_dict(),
"synthetic_distribution": synth_dist.to_dict(),
}
# 상관관계 보존 검증
numeric_cols = real.select_dtypes(include=[np.number]).columns
if len(numeric_cols) > 1:
real_corr = real[numeric_cols].corr()
synth_corr = synthetic[numeric_cols].corr()
corr_diff = (real_corr - synth_corr).abs().mean().mean()
results["correlation_preservation"] = {
"mean_absolute_diff": corr_diff
}
return results테이블 합성에서 가장 흔한 실수는 상관관계 검증을 생략하는 것입니다. 개별 컬럼의 분포가 완벽해도 컬럼 간 상관관계가 깨지면 다운스트림 모델 성능에 치명적인 영향을 미칩니다. 반드시 상관관계 행렬을 비교 검증하세요.
API 테스트, 데이터 파이프라인 검증, 애플리케이션 프로토타이핑 등에서 JSON 형식의 합성 데이터가 필요합니다. JSON Schema를 활용하면 구조적으로 정확한 데이터를 생성할 수 있습니다.
import json
from jsonschema import validate, ValidationError
USER_SCHEMA = {
"type": "object",
"properties": {
"id": {"type": "integer", "minimum": 1},
"name": {"type": "string", "minLength": 2, "maxLength": 50},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 18, "maximum": 100},
"role": {"type": "string", "enum": ["admin", "user", "editor"]},
"preferences": {
"type": "object",
"properties": {
"language": {"type": "string"},
"theme": {
"type": "string",
"enum": ["light", "dark"],
},
"notifications": {"type": "boolean"},
},
},
},
"required": ["id", "name", "email", "age", "role"],
}
JSON_GEN_PROMPT = """다음 JSON Schema에 맞는 현실적인 데이터 {count}개를 생성하세요.
Schema:
{schema}
규칙:
- 모든 필드가 스키마 제약 조건을 만족해야 합니다.
- 이메일, 이름 등은 현실적이지만 실제 존재하지 않는 값을 사용합니다.
- 다양한 값의 조합을 포함합니다.
- JSON 배열 형식으로 출력합니다."""
def generate_json_data(
schema: dict, count: int, model_fn
) -> list[dict]:
"""JSON Schema에 맞는 합성 데이터를 생성합니다."""
prompt = JSON_GEN_PROMPT.format(
schema=json.dumps(schema, indent=2, ensure_ascii=False),
count=count,
)
response = model_fn(prompt)
data = json.loads(response)
# 스키마 검증
validated = []
for item in data:
try:
validate(instance=item, schema=schema)
validated.append(item)
except ValidationError:
pass # 스키마 위반 데이터 폐기
return validatedJSON Schema에 description 필드를 상세히 작성하면 LLM이 더 현실적인 데이터를 생성합니다. 예를 들어 "description": "한국 휴대전화 번호, 010으로 시작"과 같이 명시하면 도메인에 맞는 값을 생성할 확률이 높아집니다.
Text-to-SQL 모델을 학습시키기 위해서는 자연어 질문과 그에 대응하는 SQL 쿼리 쌍이 필요합니다.
SQL_GEN_PROMPT = """다음 데이터베이스 스키마에 대해 자연어 질문과
SQL 쿼리 쌍을 생성하세요.
데이터베이스 스키마:
{db_schema}
난이도: {difficulty}
생성 수: {count}개
난이도 기준:
- 초급: 단일 테이블, 기본 SELECT/WHERE
- 중급: JOIN, GROUP BY, HAVING, 서브쿼리
- 고급: 윈도우 함수, CTE, 복합 서브쿼리, PIVOT
JSON 형식:
[
{{
"question": "자연어 질문",
"sql": "SELECT ...",
"difficulty": "난이도",
"tables_used": ["테이블명"]
}}
]"""
DB_SCHEMA_EXAMPLE = """
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT,
salary DECIMAL(10, 2),
hire_date DATE,
FOREIGN KEY (department_id) REFERENCES departments(id)
);
CREATE TABLE departments (
id INT PRIMARY KEY,
name VARCHAR(50),
location VARCHAR(100)
);
CREATE TABLE projects (
id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT,
budget DECIMAL(12, 2),
start_date DATE,
end_date DATE,
FOREIGN KEY (department_id) REFERENCES departments(id)
);
"""SQL 합성 데이터의 검증은 실제 데이터베이스에서 쿼리를 실행하여 수행합니다.
import sqlite3
def validate_sql_query(
sql: str, db_schema: str, sample_data: str
) -> tuple[bool, str]:
"""SQL 쿼리의 유효성을 실행으로 검증합니다."""
conn = sqlite3.connect(":memory:")
cursor = conn.cursor()
try:
# 스키마 생성
cursor.executescript(db_schema)
# 샘플 데이터 삽입
cursor.executescript(sample_data)
# 쿼리 실행
cursor.execute(sql)
results = cursor.fetchall()
return True, f"결과 {len(results)}행"
except Exception as e:
return False, str(e)
finally:
conn.close()멀티모달 AI를 위한 이미지-텍스트 페어 데이터는 합성 데이터의 중요한 영역입니다.
캡션 우선 접근법은 텍스트 설명을 먼저 체계적으로 생성한 후, 이미지 생성 모델(Stable Diffusion, DALL-E 등)로 대응하는 이미지를 만드는 방식입니다. 캡션의 다양성과 정확성을 더 잘 제어할 수 있습니다.
CAPTION_GEN_PROMPT = """다음 카테고리에 해당하는 이미지 캡션을 생성하세요.
카테고리: {category}
세부 주제: {subtopic}
스타일: {caption_style}
규칙:
- 시각적 요소를 구체적으로 묘사합니다.
- 색상, 구도, 개체 위치 등을 포함합니다.
- 이미지 생성 모델이 정확히 재현할 수 있을 정도로 상세합니다.
- 캡션 길이는 50~150 단어입니다.
생성할 캡션 수: {count}개"""
CAPTION_STYLES = {
"descriptive": "객관적이고 상세한 묘사",
"narrative": "이야기를 담은 서술",
"technical": "기술적 특성 중심 설명",
"alt_text": "접근성을 위한 대체 텍스트",
}
def generate_image_caption_pairs(
categories: list[dict],
caption_style: str = "descriptive",
model_fn=None,
image_gen_fn=None,
) -> list[dict]:
"""이미지-캡션 쌍을 합성 생성합니다."""
pairs = []
for cat in categories:
# 1단계: 캡션 생성
captions = model_fn(
CAPTION_GEN_PROMPT.format(
category=cat["category"],
subtopic=cat["subtopic"],
caption_style=CAPTION_STYLES[caption_style],
count=cat["count"],
)
)
# 2단계: 각 캡션에 대해 이미지 생성
for caption in captions:
image = image_gen_fn(caption)
pairs.append({
"caption": caption,
"image_path": image,
"category": cat["category"],
"style": caption_style,
})
return pairs이미지-캡션 합성의 핵심 과제는 "정렬(Alignment)"입니다. 캡션이 묘사하는 내용과 생성된 이미지가 정확히 일치해야 합니다. CLIP 모델을 활용하여 이미지-텍스트 유사도 점수를 계산하고, 임계값 이하의 쌍은 필터링하는 것이 일반적입니다.
NVIDIA Nemotron-4 340B는 합성 데이터 생성을 위해 특별히 설계된 대규모 언어 모델 패밀리입니다. Instruct, Reward, Base 세 가지 버전으로 구성되어 합성 데이터 파이프라인의 각 단계를 지원합니다.
| 모델 | 역할 | 특징 |
|---|---|---|
| Nemotron-4-340B-Instruct | 데이터 생성 | 다양한 도메인의 지시-응답 쌍 생성에 최적화 |
| Nemotron-4-340B-Reward | 품질 평가 | 생성된 데이터의 품질을 0~5 점수로 평가 |
| Nemotron-4-340B-Base | 기반 모델 | 커스텀 파인튜닝의 출발점 |
Nemotron의 핵심 가치는 생성과 평가를 하나의 통합된 파이프라인에서 수행할 수 있다는 점입니다. Reward 모델이 생성된 데이터에 대해 도움됨(Helpfulness), 정확성(Correctness), 일관성(Coherence), 복잡도(Complexity), 상세도(Verbosity) 다섯 가지 차원으로 점수를 매깁니다.
Nemotron Reward 모델의 점수를 필터링 기준으로 사용할 때, 일반적으로 4.0 이상을 임계값으로 설정합니다. 그러나 도메인에 따라 이 임계값은 조정이 필요합니다. 학술 콘텐츠는 더 높은 기준을, 일상 대화는 더 낮은 기준을 적용하는 것이 합리적입니다.
2026년 현재 사용 가능한 주요 합성 데이터 도구를 종합적으로 비교합니다.
| 도구 | 오픈소스 | 강점 | 약점 | 비용 |
|---|---|---|---|---|
| InstructLab | O | 택소노미 기반, 커뮤니티 | 규모 제한 | 무료 (컴퓨팅 비용만) |
| NVIDIA Nemotron | O | 통합 파이프라인, 대규모 | GPU 요구사항 높음 | 무료 (GPU 비용) |
| Argilla + distilabel | O | 피드백 루프, 유연성 | 설정 복잡 | 무료 |
| GPT-4o API | X | 최고 품질 | 높은 API 비용, 라이선스 | API 비용 |
| Claude API | X | 안전성, 한국어 품질 | API 비용 | API 비용 |
| 도구 | 오픈소스 | 강점 | 약점 | 비용 |
|---|---|---|---|---|
| SDV (Synthetic Data Vault) | O | 다양한 모델, 검증 내장 | 대규모 학습 느림 | 무료 |
| Gretel | 부분 | 엔터프라이즈급 프라이버시 | 클라우드 종속 | 유료 |
| K2view | X | 소스 추출, PII 발견 | 엔터프라이즈 전용 | 유료 |
| Faker + 커스텀 | O | 단순, 빠름 | 상관관계 미보존 | 무료 |
이 장에서는 텍스트를 넘어 구조화된 데이터와 멀티모달 데이터의 합성 기법을 살펴보았습니다.
다음 장에서는 합성 데이터의 생명선인 품질 검증과 필터링 파이프라인을 다룹니다. 아무리 좋은 생성 기법을 사용해도, 품질 검증 없이는 신뢰할 수 있는 합성 데이터를 만들 수 없습니다.
이 글이 도움이 되셨나요?
충실도, 유용성, 프라이버시 3계층 품질 평가 프레임워크와 LLM-as-Judge, 자동 필터링 파이프라인, 중복 제거 전략을 다룹니다.
지시-응답 쌍, 대화 데이터, 분류/NER 학습 데이터, 다국어 데이터, 코드 데이터의 합성 파이프라인을 실전 코드와 함께 구축합니다.
전통적 텍스트 증강부터 LLM 기반 증강, 어려운 예제 생성, 엣지 케이스 증강, 증강 비율 최적화까지 실전 데이터 증강 기법을 다룹니다.