Skip to content

사용 목적별 GPU 수명 정책 도입: batch / interactive / online 및 비용 가정 정정 #43

Closed

Description

@serithemage

배경

README를 읽은 사용자에게서 기본 유휴 종료 30분의 비용에 대한 피드백을 받았다. 문서의 예시 단가 $2.60/h를 가정하면 세션 종료 후 30분은 $1.30이며, 하루 2회 × 30일이면 $78이다. 월 $100–200 목표에서 큰 비중이다. 단가는 예시이며 실시간 가격 보장은 아니다.

요청 유무는 배치 작업 완료, 대화형 사용자의 휴식, 온라인 서비스의 대기 상태를 구분하지 못한다. 사용 목적별 기본 정책과 비용 설명을 도입한다.

설계 초안

모드

모드 기본 정책 비용·가용성 기준
interactive (생략 시 기본) 유휴 종료. 초기 기본 30분은 호환성을 위해 유지하고 짧은 값은 명시적으로 설정 재기동 약 8분과 유휴 비용의 균형
batch 전용 CLI 작업 래퍼로 실행. 작업 동안 요청 기반 종료를 사용하지 않고 성공·실패·취소 후 GPU 0으로 정리 작업 수명 기준
online 유휴 종료 비활성, 기동 후 최소 용량 1 유지 응답 대기 최소화. 스팟 중단 가능성은 유지
  • 모델 양자화 프로파일과 구분해 CDK -c usageMode=..., CLI --usage-mode로 노출한다.
  • 명시적 idleMinutes 등 세부 값의 우선순위를 정의하고 검증한다. batch/online에서 목적과 충돌하는 설정은 조용히 무시하지 않고 거부한다.
  • minCapacity=0은 최초 선시딩/스택 생성 단계에 필요하다. 온라인도 준비 단계에는 GPU 0, READY 이후에는 min=1을 적용한다. 명시적 down은 항상 min/desired=0으로 종료 가능해야 한다.
  • 모드 변경이 이미 있는 스택에도 실제 반영되도록 한다. 기존 스택 존재만 확인하고 새 설정을 누락하는 경로를 방지한다.
  • batch는 tkf run <model> --region <region> -- <command> [args...] 형태의 전용 소유 작업을 우선 지원한다. 인자 배열을 유지하고 셸 문자열 결합을 피한다. 엔드포인트·모델·API 키는 자식 프로세스 환경변수로 전달하고 로그에는 키를 노출하지 않는다.
  • batch는 실행 중인 다른 세션/온라인 인스턴스를 인수하거나 종료하지 않도록 소유권 조건을 확인한다. 시작 실패, 자식 실패, SIGINT/SIGTERM, 시간 제한, 정리 실패를 처리한다. SIGKILL/클라이언트 유실 시 자동 정리 보장 여부와 복구 명령을 명시한다.
  • 대화형의 ALB RequestCount 기반 감시는 실행 중 스트리밍/긴 요청을 정확하게 판별하지 못한다. 이번 변경에서 기본 유휴 시간을 성급히 단축하지 않는다. 안전한 단축에는 실행·대기 작업 수와 최근 활동을 확인하는 별도 활동 감시가 필요하다는 한계를 명시한다.
  • CloudWatch 5분 단위 평가/결측 데이터 때문에 유휴 설정은 정확한 과금 종료 시각이 아니다. 임의 값을 반올림하여 더 일찍 종료하지 않도록 유효 범위/단위를 검증한다.

비용 문서

영문·한국어·일본어 README의 “쓴 시간만큼만”, 무조건적인 “월 $100–200”, “시간 정액” 표현을 정정한다.
GPU 비용 = 시간당 단가 × (추론 + 부팅 + 유휴 실행 시간). ALB/S3/EBS 등은 별도이며, down 후 남는 비용도 명시한다.
30분/10분 유휴 예시(하루 2회·30일: $78/$26), 배치 완료 후 즉시 종료, 온라인 24시간 GPU 실행 예시($2.60 × 24 × 30 = $1,872)를 가정과 함께 제시한다.

구현 계획

  1. 공통 사용 모드/정책 해석과 CDK 연결, 입력 검증 및 합성 테스트.
  2. CLI 단일 리전·자동 배치 경로에 정책 전달/적용, 기존 스택 변경과 상태 호환성 검증.
  3. batch 작업 수명 래퍼 및 실패·신호·타임아웃 정리 테스트.
  4. README 3개 언어와 운영 안내 갱신.
  5. Ralph Loop로 구현 → 전체 테스트/타입 검사/오프라인 합성 → 리뷰/수정 반복.

완료 조건

  • 세 모드의 기본값과 명시적 설정 우선순위가 테스트로 검증된다.
  • CLI와 CDK의 정책이 일치하고 기존 스택에도 변경이 적용된다.
  • online은 요청이 없어도 종료되지 않으며 명시적 down은 가능하다.
  • batch 작업 중 무요청으로 종료되지 않고 종료·실패·취소·시간 제한 후 정리를 시도한다.
  • 소유권과 정리 실패가 검증되고, 실패 시 성공으로 보고하지 않는다.
  • 유휴 값 오류, 하위 호환성, 두 기동 경로, 비용 설명을 검증한다.
  • npm test, npm run build, 오프라인 CDK 합성을 통과한다.
  • 실제 AWS 배포/GPU 기동 없이 검증하고 배포 검증의 한계를 기록한다.

구현·테스트는 요청에 따라 Ralph Loop에서 진행한다. 설계 변경과 검증 결과는 작업 기록에 남긴다.

구현 중 설계 보완

  • 배치는 작업 중 하트비트를 보내 유휴 종료를 억제하고, 래퍼 유실에 대비한 유휴 알람은 보조 장치로 유지한다. 상태 변화·전파 지연 때문에 종료를 보장하지는 않는다.
  • 정책 변경을 위한 기존 스택 재배포에서 allowedCidrs, azs, alertEmail을 보존해야 한다. 설정을 확인할 수 없는 구버전 스택은 자동 재배포하지 않고 원래 컨텍스트를 유지한 명시적 마이그레이션을 안내한다.
  • 종료 요청이 수락된 것과 실제 인스턴스 종료·과금 중단을 구분한다.
  • 실제 로컬 자식·손자 프로세스로 취소/시간 제한 처리를 검증한다. 잠금은 동일 호스트 범위이며 호스트 간 동시 시작은 보장하지 않는다.

로컬 구현·검증 결과 (2026-10-24)

Ralph Loop에서 구현 → 테스트 → 리뷰 → 수정 반복을 수행했다. 완료 조건 표시는 아래 로컬 검증 범위에 대한 것이다.

  • 공통 정책 해석기와 CDK/CLI 연결: interactive(기본 유휴 30분), batch(tkf run), online(유휴 종료 없음·READY 후 min=1).
  • batch 실패·취소·시간 제한 정리, 로컬 잠금, 자식/손자 프로세스 종료와 종료 코드·정리 오류 보고를 구현했다.
  • 정책 변경 시 기존 IP 허용목록·AZ·알림 설정을 보존한다. 확인할 수 없는 설정은 자동 재배포하지 않는다. 구버전 스택의 기본 기동은 유지하고, 모드/유휴 정책 변경은 문서의 수동 이관 절차를 따른다.
  • README 3개 언어, 비용 근거 문서와 운영 지침을 갱신했다.
  • npx jest --runInBand: 25개 스위트, 246개 테스트 통과.
  • npm run build: exit 0.
  • npx ts-node scripts/verify-usage-mode-synth.ts: 13개 케이스 통과(정상 8, 거부 5). 공백·작은따옴표 경로에서도 13개 통과.
  • 위 로컬 검증 단계에서는 실제 AWS 배포, GPU 기동 및 실제 알람 발화를 검증하지 않았다. 이후 배포 결과는 아래에 기록한다. 호스트 간 동시 시작과 SIGKILL 이후 자동 정리는 보장하지 않으며 문서에 복구 절차를 기록했다.

구현은 PR #44로 main에 통합했다. 기능·문서·v1.1.0 버전 변경을 논리 커밋 3개로 나누고 원격 push를 확인했다.
설계·검증·반복 리뷰 기록: docs/superpowers/plans/2026-10-24-usage-modes.md.
npm/GitHub 릴리즈 게시와 registry artifact 검증을 완료해 이 이슈를 완료로 닫았다.

AWS 배포 결과 (2026-10-24)

  • 기존 서울 리전(ap-northeast-2)의 TokenForge-qwen3-coder-30b-fp8 스택에 배포 완료: CloudFormation UPDATE_COMPLETE.
  • 기존 정책 유지: UsageMode=interactive, IdleMinutes=30, ASG min=0 / desired=0 / instances=[].
  • 실제 DeploymentSettings 출력과 기존 엔드포인트, 보안·AZ·알림 설정 유지를 확인했다.
  • 변경 세트 검토 후 실행했다. Launch Template은 교체 없이 갱신됐고, 기존 latest 참조에 따른 AMI 갱신과 부팅 스크립트 주석 문자 복원이 포함됐다. GPU는 기동하지 않았다.
  • 로컬 글로벌 tkf를 검증된 소스 빌드에 연결하고 run --help, up --help, 실제 status로 새 기능을 확인했다. npm registry에 게시한 것은 아니다.
  • 서울·도쿄·미국 동부 두 리전의 pending/running GPU 잔존 여부를 확인했으며 모두 없었다.
  • 실제 추론, batch 작업 실행, online 상시 가동, 알람 발화는 이번 배포 검증에서 수행하지 않았다.
  • 배포·검증도 Ralph Loop로 수행했다. 상세 운영 기록은 기존 설계·검증 문서의 실제 배포 절에 추가했다. 이후 코드 커밋·원격 push와 PR 통합을 완료했으며, 릴리즈 진행 상황은 아래에 기록한다.

v1.1.0 릴리즈 완료

  • GitHub Release v1.1.0: 게시 완료, draft/prerelease 아님.
  • npm @roboco/token-forge 1.1.0: 실제 registry 게시 및 latest=1.1.0 확인.
  • PR #44를 main에 통합했고, 논리 커밋 3개를 보존했다. main 및 v1.1.0 태그 대상은 b35b01873714844d55dc798d5238b7a5c0938c5a로 일치한다.
  • 테스트 246개·빌드·PR/main CI·CodeQL 통과. 검증 tarball에서 버전 및 새 CLI 명령을 확인했다.
  • registry에서 새로 내려받은 tarball의 SHA-256이 검증된 파일과 일치했다: 45bc6324a8f87bff36e703ca2b6b979bca8217840b80d4f202c7d50a683de6be.
  • 기존 Release workflow는 npm 게시 인증 오류(E404)로 실패했다. 재로그인 및 게시용 보안키 인증 후 동일한 검증 tarball을 수동 게시해 복구했다. 이 수동 artifact에는 CI provenance를 첨부하지 않았으며 릴리즈 노트에도 기록했다. 자동 릴리즈용 NPM_TOKEN 인증은 별도 점검이 필요하다.
  • npm과 GitHub의 실제 게시를 확인한 뒤, 사용자 요청에 따라 이슈를 완료로 닫는다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions