Java를 CUDA로 직접 컴파일하는 이 프레임워크: 정말 llama.cpp와 맞설 수 있을까?
요약
University of Manchester의 TornadoVM 팀이 개발한 jitLLM은 Java 바이트코드를 CUDA와 cuTile로 직접 컴파일하여 LLM 추론을 NVIDIA GPU에서 실행하는 프레임워크입니다. 이 엔진은 C++이나 Python 사이드카 없이 순수 Java 환경에서 Llama 3, Mistral 등 다양한 모델의 추론 루프를 구현하며, 핵심 행렬 연산을 JIT-컴파일하여 성능을 확보합니다.
핵심 포인트
- Java 바이트코드를 CUDA 커널로 직접 컴파일하는 혁신적인 접근 방식입니다.
- C++이나 Python 사이드카 없이 순수 Java 환경에서 LLM 추론이 가능해집니다.
- TornadoVM 플러그인을 활용하여 핵심 행렬 연산을 GPU 가속화합니다.
- llama.cpp 대비 90% 성능을 주장하지만, 독립적인 검증이 필요합니다.
로컬 AI를 다루는 모든 Java 팀은 같은 이야기를 합니다. 깨끗한 Spring Boot나 Quarkus 서비스를 구축하고, 누군가 "우리 자체 GPU에서 추론이 필요해"라고 말하면, 갑자기 깔끔했던 JVM 스택에 Python 사이드카가 덕지덕지 붙게 됩니다. PyTorch, CUDA 툴킷, 두 번째 Dockerfile, 두 번째 CVE 세트, 그리고 자신 애플리케이션의 양쪽 절반을 연결하는 REST 호출이 생깁니다.
10월 8일, r/LocalLLaMA에서 프로젝트 하나가 돌기 시작했는데, 이 프로젝트는 정확히 그러한 고통을 공격합니다. 즉, Java 바이트코드를 CUDA와 cuTile로 컴파일하여 LLM 추론을 NVIDIA GPU에서 실행하는 Java 프레임워크이며, 그 성능은 llama.cpp의 90%에 달한다고 주장합니다. C++ 코드도 없고, Python 프로세스도 없고, 사이드카도 없습니다.
이 프로젝트는 University of Manchester의 TornadoVM 팀이 Red Hat과 협력하여 만든 jitLLM입니다. 제가 아직 제 하드웨어에서 직접 실행해 보지 않았기 때문에, 이것은 벤치마크 보고서가 아닌 완전 공개 분석 글입니다. 아래 내용은 모두 해당 프로젝트 자체 페이지, TornadoVM 블로그, 그리고 발표 관련 토론에서 가져온 것입니다. 하지만 그 뒤의 엔지니어링은 실제적이며 문서화되어 있어, 설령 사용해 보지 않더라도 이해할 가치가 있습니다.
jitLLM이 실제로 무엇인지
래퍼(wrapper)가 아닌 Java 네이티브 추론 엔진입니다. jitLLM (Java Inference Tornado toolkit)은 Llama 3, Mistral, Qwen 2.5, Qwen 3, Phi-3, IBM Granite, Devstral 2 모델을 GGUF 형식으로 실행합니다. llama.cpp를 호출하거나 HTTP를 통해 Ollama를 호출하지 않습니다. 트랜스포머 추론 루프 자체가 Java로 작성되었으며, 무거운 수학 연산은 런타임에 GPU 커널로 JIT-컴파일됩니다.
내부 GPU 컴파일러는 TornadoVM입니다. 이것이 주장의 개연성을 높이는 부분입니다. TornadoVM은 JDK의 오픈 소스 플러그인으로, 어노테이션된 Java 바이트코드를 받아 OpenCL, PTX/CUDA 또는 SPIR-V로 컴파일합니다. 이 프로젝트는 맨체스터 대학교에서 나와 수년간 활발하게 개발되어 왔습니다. jitLLM은 본질적으로 그 위에 구축된 LLM 애플리케이션 계층입니다: 루프는 Java로 구성되고, TornadoVM이 핵심 행렬 연산을 CUDA 커널로 변환하며, 기존 CUDA 라이브러리를 Java 코드에서 직접 바인딩할 수도 있습니다.
GPULlama3.java에서 발전했습니다. 이 엔진은 UNIMAN의 순수 Java Llama3.java 프로젝트를 GPU 가속화한 포크였던 GPULlama3.java로 시작되었습니다. 이는 llama.cpp가 사용하는 것과 동일한 형식인 표준 GGUF 파일을 읽고, GPU가 없을 경우 CPU 경로로 폴백(fallback)합니다.
90%라는 주장은 정확한 범위가 필요합니다. Reddit이나 애그리게이터 사이트에서 돌고 있는 숫자는 jitLLM이 NVIDIA GPU를 이용한 로컬 추론에서 llama.cpp 성능의 약 90%에 도달한다는 것입니다. 이는 프로젝트 자체 녹화본에서 RTX 5090으로 시연되었습니다. 두 가지 솔직한 주의사항이 있습니다. 첫째, 이것은 독립적인 벤치마크가 아니라 이 프로젝트의 주장입니다. 둘째, llama.cpp는 수년간 커널 최적화를 거친 고도로 손질된 C++/CUDA 코드베이스입니다. 컴파일된 Java로 이를 10% 이내로 구현하고, 그것이 다양한 하드웨어와 양자화 형식에서 유지된다면 진정으로 놀라운 일일 것입니다. 우리가 실제로 구동하는 일반적인 RTX 4060과 Q4 모델에 대해 누군가 재현할 때까지는 기대되는 것으로 간주하십시오.
실제 관점에서 'Java를 CUDA로 컴파일'한다는 것의 의미**
일반적인 반론은 Java가 JNI(Java Native Interface)와 네이티브 라이브러리 없이는 GPU에 접근할 수 없다는 것입니다. TornadoVM은 다른 실행 모델을 통해 이를 우회합니다.
• 어노테이션된 바이트코드가 커널이 됩니다. 메서드에 GPU 실행을 표시하면, TornadoVM의 JIT 컴파일러가 이를 대상 백엔드로 낮춥니다(lower). 최신 툴체인을 사용하는 NVIDIA 환경에서는 런타임에 CUDA C 및 cuTile 코드를 생성하는 것을 포함합니다.
• 메모리가 할당되는 것이 아니라 관리됩니다. TornadoVM은 가능한 경우 Java 메모리를 재사용하고 장치 전송을 처리하여, CUDA API를 사용하여 수동으로 작성해야 하는 대부분의 보일러플레이트(boilerplate) 코드를 제거합니다.
• 백엔드 선택은 런타임 속성입니다. 동일한 코드가 CUDA, OpenCL 또는 SPIR-V를 대상으로 할 수 있으므로 NVIDIA 하드웨어에 종속되지 않습니다. Apple Silicon 및 기타 OpenCL 지원 장치도 범위 내에 있습니다.
Java Vector API와 Panama 작업들을 따라왔다면, 이것은 같은 아이디어의 계열을 더 발전시킨 것입니다. JVM을 폐쇄된 정원(walled garden)으로 취급하는 것을 멈추고, 그 바이트코드가 아래에 있는 어떤 하드웨어로든 컴파일되도록 하는 것입니다.
작업 팀에게 흥미로운 부분
순수 성능이 헤드라인이지만, 통합 스토리야말로 이 프레임워크가 주목할 만하다고 생각하는 이유입니다.
이는 공식 LangChain4j 추론 엔진입니다. langchain4j-jitllm을 추가하고 onGPU(true)를 사용하여 JitLLMChatModel을 구성하면, 모든 LangChain4j AI 서비스, 도구 호출 에이전트 및 검색 파이프라인이 사용자의 GPU에서 실행됩니다. ChatLanguageModel 추상화 덕분에 나머지 코드는 추론이 어디서 발생하는지 알거나 신경 쓰지 않습니다.
Quarkus 확장도 있습니다. quarkus-langchain4j-jitllm은 모델을 CDI 빈(bean)으로 노출합니다. TornadoVM 팀은 Red Hat과 함께 EU 자금을 지원받는 AERO 프로젝트의 일환으로, 순수 Java로 GPU 추론을 수행하는 표준 Quarkus REST 리소스를 시연했습니다. 그들의 워크스루에 따르면, 전체 연결 과정은 Quarkus 속성(property)이 jitLLM을 추론 엔진으로 선택하고, ChatModel 빈을 주입하는 REST 리소스가 포함됩니다. 개발자 입장에서 보면 OpenAI나 Ollama를 호출하는 것과 동일해 보입니다. 바로 이 유사성이 핵심입니다: tornadovm.org의 하위 기사는 Quarkus에서 LangChain4j를 거쳐 GPULlama3로, 다시 GPU까지 이어지는 전체 체인을 보여주지만, CUDA를 언급하는 코드는 전혀 없습니다.
전체 스택을 위한 단일 JVM 프로세스. Python 인터프리터도 없고, 모델 서버 프로세스도 없고, HTTP 통신 과정(hop)도 없으며, 두 번째 로깅 및 모니터링 설정도 필요하지 않습니다. 헬스케어, 금융 등 데이터 상주 규정(data residency rules)이 있는 분야의 팀에게
이것이 얼마나 오랫동안 준비되어 왔는지 아는 것도 중요합니다. Quarkus 통합은 EU 기금 지원 AERO 프로젝트의 일환으로 맨체스터 대학교와 Red Hat 간의 협력으로 2026년 6월 TornadoVM 블로그에서 시연된 바 있습니다. 이번 10월의 관심은 갑작스러운 등장이 아닙니다. 이는 초기 연구 데모가 Maven 아티팩트와 공식 프레임워크 통합을 갖춘 출판된 1.0.0 툴킷으로 성숙해진 지점입니다. 이러한 진행 과정, 즉 연구 프로젝트에서 통합을 거쳐 독립형 툴킷이 되는 것은 JVM 생태계에서 무언가가 현실화되는 일반적인 형태입니다.
사용해서는 안 될 경우 (When you should NOT use it)
회의론은 정당하며, 이 프로젝트 자체의 포지셔닝도 그러한 회의론을 불러일으킵니다.
- 아직 초기 단계입니다. 1.0.0 버전은 젊은 프로젝트이며, LangChain4j 통합은 여전히 베타 아티팩트입니다. 프로덕션 팀들은 제품 출시를 여기에 걸기보다는 관찰하고, 프로토타이핑하며, 독립적인 벤치마크 결과를 기다려야 합니다.
- 순수 로컬 추론(raw local inference)의 안전한 기본값은 여전히 llama.cpp입니다. 만약 귀하의 아키텍처가 이미 'llama.cpp 서버 + 얇은 JVM 클라이언트'라면, 그것은 작동하며, 검증되었고, 여기서 무언가가 변경하도록 강요하지 않습니다. llama.cpp 주변의 집계 및 양자화(quantization) 생태계는 몇 년 앞서 있습니다.
- 대규모 배치 서빙(Batch serving at scale)은 vLLM 영역입니다. r/LocalLLaMA 포럼에서는 이를 'Java vLLM과 유사하다'고 언급했지만, vLLM의 강점인 연속 배치 처리(continuous batching)와 높은 동시성 처리량(high-concurrency throughput)은 단일 스트림 로컬 추론과는 다른 문제입니다. jitLLM은 추론 팜(inference-farm) 영역이 아닌 노트북 및 단일 서버 니치에서 경쟁합니다.
- 현재는 NVIDIA 중심입니다. CUDA와 cuTile이 시연된 경로입니다. OpenCL과 SPIR-V 백엔드는 존재하지만, 주장되는 성능 수치는 NVIDIA의 수치입니다.
JVM에서의 로컬 추론을 위한 의사결정 체크리스트
2026년 10월 기준으로 제가 실제로 저장해 둘 만한 핵심 내용은 다음과 같습니다:
- 프로토타입 또는 취미 프로젝트로 Java에서 GPU 속도를 원할 때: jitLLM이 존재하는 가장 직접적인 방법입니다. Maven 아티팩트를 추가하고, GGUF 파일에 연결한 다음,
onGPU(true)를 설정하기만 하면 됩니다. - 운영 환경의 Spring Boot 또는 Quarkus 앱으로 데이터가 서버를 벗어날 수 없을 때: jitLLM을 사용하거나 (초기 단계 리스크를 감수한다면) Ollama/llama.cpp를 제공자로 사용하는 LangChain4j가 적합합니다. 어느 쪽이든, 나중에 교체할 수 있도록
ChatModel추상화를 유지하는 것이 중요합니다. - 높은 동시성 서빙(High-concurrency serving), 많은 병렬 세션: vLLM 또는 추론 팜(inference farm)을 사용해야 합니다. 현재로서는 Java 네이티브 추론이 이 작업에 적합한 도구가 아닙니다.
- 단순히 로컬 LLM을 실험해 볼 때: UI가 있는 llama.cpp를 사용하는 것이 가장 간단하고 작동하는 방법입니다.
더 깊은 핵심은 이 프로젝트 하나보다 큽니다. 지난 10년간
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기