728x90
반응형
SMALL

안녕하세요.
이번 편에서는 딥러닝을 부드러운 비유와 짧은 예시로 정리하고,
요즘 핵심인 어텐션과 트랜스포머를
Java에서 어떻게 손에 잡히게 다뤄볼 수 있는지까지 안내해보겠습니다.
1) 딥러닝을 한 문장으로
데이터를 보고 함수의 모양(파라미터)을 스스로 조정하는 모델입니다.
입력 → 레이어(계산) → 출력, 그리고 틀린 만큼 되돌려 수정(역전파) 하면서 조금씩 좋아집니다.
- 레이어: 여러 개의 선형 변환 + 비선형 활성함수(ReLU 등)로 쌓습니다.
- 학습 루프: 예측 → 손실 계산 → 경사하강으로 가중치 조정 → 반복합니다.
- 과적합: 훈련 데이터만 외우지 않도록 드롭아웃, 정규화, 조기 종료를 사용합니다.
2) 이미지엔 CNN, 순서엔 RNN — 그리고 한계
- CNN: 이미지처럼 ‘가까운 픽셀끼리 관련 있다’는 가정으로 합성곱 필터를 학습합니다.
- RNN/LSTM: 문장처럼 순서가 중요한 데이터를 차례로 읽습니다.
- 한계: 긴 문맥이 약하고, 입력을 순차로 처리해 병렬화가 어렵습니다.
3) 어텐션(Attention)의 직관
사람이 문장을 읽을 때 중요한 단어에 더 집중하듯, 모델도 “어디를 볼지” 가중치를 배웁니다.
- 핵심 개념: Query, Key, Value
- 단어마다 Query와 Key를 만들어 유사도를 구합니다.
- 유사도를 확률(가중치) 로 바꾸고,
- 그 가중치로 Value를 가중 평균해 새 표현을 만듭니다.
- 이 과정을 자기 자신에게 적용하면 Self-Attention입니다. 단어 간 관계를 한 번에 포착할 수 있습니다.
4) 트랜스포머(Transformer) 한 눈에
RNN의 순차 처리 한계를 넘기 위해 입력을 한꺼번에 병렬 처리합니다.
- 입력 임베딩 + 위치 정보(Positional Encoding)
- [멀티헤드 어텐션] → [피드포워드 네트워크] 블록을 N번 반복
- 각 블록에는 잔차 연결(Residual) 과 레이어 정규화가 있어 학습을 안정화합니다.
- 인코더/디코더 구조: 번역 등 시퀀스-투-시퀀스는 인코더+디코더를,
- 언어모델(챗봇 등) 은 보통 디코더 블록을 쌓아 씁니다.
5) “모델이 말을 하는” 간단한 원리
언어모델은 다음 토큰(단어 조각)의 확률을 예측합니다.
생성 시에는 확률이 높은 토큰을 고르는 전략을 씁니다.
- Greedy: 그때그때 가장 높은 확률 하나 선택 → 안전하지만 단조롭습니다.
- Top-k / Top-p: 상위 k개 또는 누적확률 p 이하 후보에서 무작위 샘플링 → 더 자연스럽습니다.
- 온도(temperature): 랜덤성 강도를 조절합니다.
6) Java에서 바로 만져보기: DJL로 트랜스포머 추론
Python 없이도 사전학습 모델을 불러 간단 추론을 해볼 수 있습니다. 아래는 마스크 채우기(Fill-Mask) 예시입니다.
Maven 의존성 (예시)
<dependency>
<groupId>ai.djl</groupId>
<artifactId>api</artifactId>
<version>0.27.0</version>
</dependency>
<dependency>
<groupId>ai.djl.huggingface</groupId>
<artifactId>tokenizers</artifactId>
<version>0.27.0</version>
</dependency>
<dependency>
<groupId>ai.djl.huggingface</groupId>
<artifactId>translators</artifactId>
<version>0.27.0</version>
</dependency>
<dependency>
<groupId>ai.djl.pytorch</groupId>
<artifactId>pytorch-engine</artifactId>
<version>0.27.0</version>
</dependency>
코드 스니펫
import ai.djl.ModelException;
import ai.djl.huggingface.translator.FillMaskTranslatorFactory;
import ai.djl.inference.Predictor;
import ai.djl.modality.Classifications;
import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ZooModel;
import ai.djl.training.util.ProgressBar;
public class FillMaskDemo {
public static void main(String[] args) throws Exception {
var criteria = Criteria.builder()
.optApplication(ai.djl.Application.NLP.FILL_MASK)
.setTypes(String.class, Classifications.class)
// 변경점: 허깅페이스 사전학습 모델 지정 (bert-base-uncased 등)
.optModelUrls("djl://ai.djl.huggingface.pytorch/bert-base-uncased")
.optTranslatorFactory(new FillMaskTranslatorFactory())
.optProgress(new ProgressBar())
.build();
try (ZooModel<String, Classifications> model = criteria.loadModel();
Predictor<String, Classifications> predictor = model.newPredictor()) {
var input = "AI is changing the <mask> world.";
var result = predictor.predict(input);
System.out.println(result.topK(5)); // 상위 5개 후보와 확률
} catch (ModelException e) {
e.printStackTrace();
}
}
}
포인트
- “처음부터 학습”이 아니라 사전학습 모델 재사용으로 시작하면 빠르고 안정적입니다.
- 운영에서는 ONNX Runtime Java로 변환해 경량 추론을 쓰거나, CPU/GPU 옵션을 환경에 맞춰 선택합니다.
- 토큰화 버전이 모델과 반드시 일치해야 합니다.
7) 운영 관점의 간단 체크리스트
- 지연시간: 모델 크기·디코딩 전략이 영향을 줍니다. 캐시와 배치 추론을 고려합니다.
- 메모리: FP16/INT8 양자화를 검토하면 비용을 줄일 수 있습니다.
- 모니터링: 입력 분포 변화, 응답 길이, 금지어 필터링 등을 로그로 점검합니다.
딥러닝의 뼈대와 어텐션, 트랜스포머의 핵심을 직관적으로 살펴보고,
Java에서 바로 시도할 수 있는 추론 예제를 함께 보았습니다.
4편에서는 전이학습/파인튜닝, 프롬프트 설계, 평가·모니터링, 비용·지연시간 최적화를 사례 중심으로
정리해보겠습니다.
읽어주셔서 감사합니다.
728x90
반응형
LIST
'TIPS' 카테고리의 다른 글
| RSA 핵심 원리와 웹에서의 안전한 쓰임새 part.1 (1/3) (0) | 2025.10.27 |
|---|---|
| 인공지능의 기초 원리부터 고급까지 part.4 (4/4) (0) | 2025.09.29 |
| 인공지능의 기초 원리부터 고급까지 part.2 (2/4) (0) | 2025.09.15 |
| 인공지능의 기초 원리부터 고급까지 part.1 (1/4) (0) | 2025.09.08 |
| 실무용 페이징 전략! OFFSET/LIMIT를 넘어 Keyset Pagination까지 (4) | 2025.09.01 |