본문 바로가기

TIPS

인공지능의 기초 원리부터 고급까지 part.4 (4/4)

728x90
반응형
SMALL

 

안녕하세요.

 

마지막 편에서는 실무에서 바로 쓰이는 네 가지를 한 번에 정리해보겠습니다.

 

1) 전이학습/파인튜닝, 2) 프롬프트 설계, 3) 평가·모니터링, 4) 성능·비용 최적화입니다.

예시는 모두 Java 관점으로 소개해보겠습니다.


 

1) 전이학습(Transfer Learning)·파인튜닝(Fine-tuning)

 

언제 쓰나요?

  • 데이터가 많지 않지만 도메인 특화 성능이 필요할 때
  • 이미지 분류, 문장 분류, 키워드 추출 등

 

도구 선택

  • 추론만 필요 → DJL + 사전학습 모델
  • 미세 조정 필요 → DJL(간단 학습) 또는 Python에서 학습→ONNX로 내보내기→Java 추론

DJL로 “헤드만” 바꿔 미세 조정 (개념 스니펫)

 

// 변경점: 사전학습 백본을 로드하고, 마지막 분류 레이어(헤드)만 교체합니다.
var criteria = Criteria.builder()
    .optApplication(Application.CV.IMAGE_CLASSIFICATION)
    .optFilter("backbone", "resnet50")           // 변경점: 백본 선택
    .setTypes(Image.class, Classifications.class)
    .build();

try (ZooModel<Image, Classifications> pretrained = criteria.loadModel()) {
    // 변경점: 마지막 레이어를 우리 도메인 클래스로 교체하고 학습 루프를 구성합니다.
    // DJL의 Blocks API로 classifier head를 갈아끼우는 흐름을 사용합니다.
    // (실습에선 Trainer, Loss, Optimizer, Epoch 등을 설정합니다)
}
 

학습 코드는 프로젝트마다 길어지기 때문에, 처음에는 Python으로 파인튜닝 → ONNX Export → Java 추론 루트를 추천드립니다.

 


2) 프롬프트 설계(LLM 활용) — Java에서의 접근

 

상황

  • LLM API 사용 또는 로컬 LLM 추론(ONNX/DJL)
  • 프롬프트는 “지시 + 맥락 + 형식” 세 박스로 생각합니다.

최소 템플릿 예시

 

[지시] 아래 입력을 한 문장으로 요약해 주세요. 전문용어는 유지합니다.
[형식] 출력은 JSON {"summary": "..."} 형식으로만 응답해 주세요.
[입력]
---
{문서 본문}
---
 
 

  • 역할(role) + 예시(few-shot) + 출력 형식(schema) 를 명확히 합니다.
  • 긴 맥락은 키워드/요약 → 추가 조회 → 재요약처럼 단계별로 나눠봅니다.
  • 민감 정보가 있다면 프롬프트 앞단에서 마스킹을 적용합니다.

3) 평가(Evaluation)·모니터링(Monitoring)

 

오프라인 평가

  • 분류/검색: 정확도, F1, ROC-AUC, MRR, nDCG
  • 요약/생성: 참조 데이터가 있으면 ROUGE/BLEU, 없으면 규칙·채점 기준으로 자동 평가
  • 베이스라인을 먼저 만들고, 샘플 50~100건이라도 사람이 검수해 지표와 체감 차이를 맞춰봅니다.

온라인 모니터링

  • Micrometer + Prometheus/Grafana로 p95 지연시간, 오류율, 요청 수 집계
  • 입력 길이/출력 길이 히스토그램, 토큰 사용량 로그
  • OpenTelemetry로 추론 구간 트레이싱
  • 민감도 높은 서비스는 안전 필터(금지어, PII 마스킹) 를 미들웨어로 둡니다.

4) 성능·비용 최적화 (Java 서빙 체크리스트)

 

모델·런타임

  • ONNX Runtime Java: CPU 추론 최적화가 잘 되어 있습니다.
  • 양자화(Quantization): INT8/FP16로 메모리·지연시간 절감
  • Distillation: 더 작은 학생 모델로 비용 절감

서빙 패턴

  • 모델 재사용: 애플리케이션 시작 시 로드, 요청마다 재로딩 금지
  • 토큰화 캐시: 반복 입력은 토크나이즈 결과를 캐시
  • 미니배치(batch): 같은 타임슬롯 요청을 묶어 처리
  • 스레드 풀: CPU 코어에 맞게 executor 크기 조정(과도한 스레드 금지)
  • Warm-up: 배포 직후 워밍업 요청으로 JIT·캐시를 채워둡니다.

예: ONNX Runtime Java 추론 스니펫

 

// 변경점: Session을 애플리케이션 전역에서 재사용합니다.
OrtEnvironment env = OrtEnvironment.getEnvironment();
OrtSession.SessionOptions opts = new OrtSession.SessionOptions();

// 변경점: CPU 최적화 옵션/스레드 조정
opts.setIntraOpNumThreads(Runtime.getRuntime().availableProcessors());

try (OrtSession session = env.createSession("model.onnx", opts)) {
    // 입력 텐서 준비
    OnnxTensor input = OnnxTensor.createTensor(env, inputNdArray);
    Map<String, OnnxTensor> feeds = Map.of("input_ids", input);

    OrtSession.Result out = session.run(feeds); // 추론
    // 결과 파싱...
}
 

 


5) Spring Boot 연동 한 번에 보기 (개념)

 

  • /predict REST 엔드포인트
  • 전역 Model/Session 싱글톤
  • 요청 로깅(입력 길이, 소요 시간), 서킷 브레이커(타임아웃), 캐시(동일 입력)

 

@RestController
@RequiredArgsConstructor
public class PredictController {
    private final PredictorService predictor; // 변경점: 모델 세션을 내부에서 재사용

    @PostMapping("/predict")
    public Response predict(@RequestBody Request req) {
        long t0 = System.nanoTime();
        var out = predictor.infer(req.getText());
        long ms = (System.nanoTime() - t0)/1_000_000;
        // 변경점: 지연시간·길이 등 메트릭 기록
        return new Response(out, ms);
    }
}
 

6) 데이터·보안 간단 원칙

 

  • 입력 데이터는 최소 수집·목적 외 사용 금지
  • 저장 전 익명화/마스킹
  • 모델 파일·가중치에 무결성 체크섬
  • 로그에는 민감 정보 남기지 않기

이상 4편입니다.

전이학습/파인튜닝부터 프롬프트 설계, 평가·모니터링, 성능·비용 최적화까지

Java 실전 흐름으로 정리해보았습니다.

 

AI는 if가 아니라 학습과 최적화의 연속이라는 시리즈의 큰 흐름을 마치고,

이후에는 실제 프로젝트 보일러플레이트(스켈레톤)배포 체크리스트를 따로 정리해보겠습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형
LIST