Jlama

tjakeApache-2.0长期未更新

用纯 Java 实现的现代 LLM 推理引擎,支持 LLaMA、GPT 等 Transformer 模型,借助 SIMD 加速在 JVM 上直接跑大模型推理。

Jlama is a modern LLM inference engine for Java

v0.8.4发布于 2025-01-01 19:28 UTC1,309star166fork同步于 2026-11-07 07:31 UTC

怎么上手

由 README 提炼,执行前请确认
curl -Ls https://sh.jbang.dev | bash -s - app setup
jbang app install --force jlama@tjake
jlama restapi tjake/Llama-3.2-1B-Instruct-JQ4 --auto-download
硬件要求按 README 说明

README 未说明具体显存或 GPU 型号要求,仅提到后端可选 Panama Vector(默认)、Native SIMD 和实验性 WebGPU。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

纯 Java 的 LLM 推理引擎,让你直接在 Java 应用里跑大模型

用纯 Java 实现的现代 LLM 推理引擎,支持 LLaMA、GPT 等 Transformer 模型,借助 SIMD 加速在 JVM 上直接跑大模型推理。

核心能力

  • 实现 Paged Attention 管理 KV 缓存
  • 支持 Mixtral 等 Mixture of Experts 模型
  • 内置 Tool Calling 与 Embedding 生成
  • 读取 HuggingFace SafeTensors 模型与分词器
  • 支持 Q8/Q4 量化与分布式推理

容易踩的坑

需要 Java 20 及以上,且用到 Java 21 预览特性,需加 --enable-preview 和 jdk.incubator.vector 模块;模型不会自动就位,CLI 要加 --auto-download 或先用 download 命令拉取;restapi 默认监听 8080 端口,可能与其他服务冲突。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.8.4
  1. v0.8.4最新正式版2025-01-01 · 2025-01-01 19:28 UTC

    What's Changed

    New Contributors

    Full Changelog: https://github.com/tjake/Jlama/compare/v0.8.3...v0.8.4

  2. v0.8.32024-11-24 · 2024-11-24 21:27 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/tjake/Jlama/compare/v0.8.2...v0.8.3

  3. v0.8.22024-11-05 · 2024-11-05 04:37 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/tjake/Jlama/compare/v0.8.1...v0.8.2

  4. v0.8.12024-11-04 · 2024-11-04 04:05 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/tjake/Jlama/compare/v0.8.0...v0.8.1

  5. v0.8.02024-10-30 · 2024-10-30 00:45 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/tjake/Jlama/compare/v0.7.0...v0.8.0

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    🦙 Jlama: A modern LLM inference engine for Java

    Maven Central Version License Discord DeepWiki

    🚀 Features

    Model Support:

    • Gemma & Gemma 2 Models
    • Llama & Llama2 & Llama3 Models
    • Mistral & Mixtral Models
    • Qwen2 Models
    • IBM Granite Models
    • GPT-2 Models
    • BERT Models
    • BPE Tokenizers
    • WordPiece Tokenizers

    Implements:

    • Paged Attention
    • Mixture of Experts
    • Tool Calling
    • Generate Embeddings
    • Classifier Support
    • Huggingface SafeTensors model and tokenizer format
    • Support for F32, F16, BF16 types
    • Support for Q8, Q4 model quantization
    • Fast GEMM operations
    • Distributed Inference!

    Jlama requires Java 20 or later and it built with the following backends:

    🤔 What is it used for?

    Add LLM Inference directly to your Java application. To learn more read the DeepWiki docs.

    🔬 Quick Start

    🕵️‍♀️ How to use as a local client (with jbang!)

    Jlama includes a command line tool that makes it easy to use.

    The CLI can be run with jbang.

    #Install jbang (or https://www.jbang.dev/download/)
    curl -Ls https://sh.jbang.dev | bash -s - app setup
    
    #Install Jlama CLI (will ask if you trust the source)
    jbang app install --force jlama@tjake
    

    Now that you have jlama installed you can download a model from huggingface and chat with it. Note I have pre-quantized models available at https://hf.co/tjake

    # Run the openai chat api and UI on a model
    jlama restapi tjake/Llama-3.2-1B-Instruct-JQ4 --auto-download
    

    open browser to http://localhost:8080/

    Usage:
    
    jlama [COMMAND]
    
    Description:
    
    Jlama is a modern LLM inference engine for Java!
    Quantized models are maintained at https://hf.co/tjake
    
    Choose from the available commands:
    
    Inference:
      chat                 Interact with the specified model
      restapi              Starts a openai compatible rest api for interacting with this model
      complete             Completes a prompt using the specified model
    
    Distributed Inference:
      cluster-coordinator  Starts a distributed rest api for a model using cluster workers
      cluster-worker       Connects to a cluster coordinator to perform distributed inference
    
    Other:
      download             Downloads a HuggingFace model - use owner/name format
      list                 Lists local models
      quantize             Quantize the specified model
      rm                   Removes local model
      version              Display JLama version information
    

    👨‍💻 How to use in your Java project

    The main purpose of Jlama is to provide a simple way to use large language models in Java.

    The simplest way to embed Jlama in your app is with the Langchain4j Integration.

    If you would like to embed Jlama without langchain4j, add the following maven dependencies to your project:

    
    <dependency>
      <groupId>com.github.tjake</groupId>
      <artifactId>jlama-core</artifactId>
      <version>${jlama.version}</version>
    </dependency>
    
    <dependency>
      <groupId>com.github.tjake</groupId>
      <artifactId>jlama-native</artifactId>
      <!-- supports linux-x86_64, macos-x86_64/aarch_64, windows-x86_64
           Use https://github.com/trustin/os-maven-plugin to detect os and arch -->
      <classifier>${os.detected.name}-${os.detected.arch}</classifier>
      <version>${jlama.version}</version>
    </dependency>
    
    

    jlama uses Java 21 preview features. You can enable the features globally with:

    export JDK_JAVA_OPTIONS="--add-modules jdk.incubator.vector --enable-preview"
    

    or enable the preview features by configuring maven compiler and failsafe plugins.

    Then you can use the Model classes to run models:

     public void sample() throws IOException {
        String model = "tjake/Llama-3.2-1B-Instruct-JQ4";
        String workingDirectory = "./models";
    
        String prompt = "What is the best season to plant avocados?";
    
        // Downloads the model or just returns the local path if it's already downloaded
        File localModelPath = new Downloader(workingDirectory, model).huggingFaceModel();
    
        // Loads the quantized model and specified use of quantized memory
        AbstractModel m = ModelSupport.loadModel(localModelPath, DType.F32, DType.I8);
    
        PromptContext ctx;
        // Checks if the model supports chat prompting and adds prompt in the expected format for this model
        if (m.promptSupport().isPresent()) {
            ctx = m.promptSupport()
                    .get()
                    .builder()
                    .addSystemMessage("You are a helpful chatbot who writes short responses.")
                    .addUserMessage(prompt)
                    .build();
        } else {
            ctx = PromptContext.of(prompt);
        }
    
        System.out.println("Prompt: " + ctx.getPrompt() + "\n");
        // Generates a response to the prompt and prints it
        // The api allows for streaming or non-streaming responses
        // The response is generated with a temperature of 0.7 and a max token length of 256
        Generator.Response r = m.generate(UUID.randomUUID(), ctx, 0.0f, 256, (s, f) -> {});
        System.out.println(r.responseText);
     }
    

    Or you can use a Builder API:

     public void sample() throws IOException {
        String model = "tjake/Llama-3.2-1B-Instruct-JQ4";
        String workingDirectory = "./models";
    
        String prompt = "What is the best season to plant avocados?";
    
        // Downloads the model or just returns the local path if it's already downloaded
        File localModelPath = new Downloader(workingDirectory, model).huggingFaceModel();
    
        // Loads the quantized model and specified use of quantized memory
        AbstractModel m = ModelSupport.loadModel(localModelPath, DType.F32, DType.I8);
    
        PromptContext ctx;
        // Checks if the model supports chat prompting and adds prompt in the expected format for this model
        if (m.promptSupport().isPresent()) {
            ctx = m.promptSupport()
                    .get()
                    .builder()
                    .addSystemMessage("You are a helpful chatbot who writes short responses.")
                    .addUserMessage(prompt)
                    .build();
        } else {
            ctx = PromptContext.of(prompt);
        }
    
        System.out.println("Prompt: " + ctx.getPrompt() + "\n");
        // Generates a response to the prompt and prints it
        // The api allows for streaming or non-streaming responses
        // The response is generated with a temperature of 0.7 and a max token length of 256
        Generator.Response r = m.generateBuilder()
                .session(UUID.randomUUID()) //By default, UUID.randomUUID()
                .promptContext(ctx) // Required or use prompt(String text)
                .ntokens(256) //By default, 256
                .temperature(0.0f) //By default, 0.0f
                .onTokenWithTimings((s, aFloat) -> {}) //By default, (s, aFloat) -> {}, nothing
                .generate();
    
        System.out.println(r.responseText);
     }
    

    You can simplify promptSupport using:

     public void sample() throws IOException {
        String model = "tjake/Llama-3.2-1B-Instruct-JQ4";
        String workingDirectory = "./models";
    
        String prompt = "What is the best season to plant avocados?";
    
        // Downloads the model or just returns the local path if it's already downloaded
        File localModelPath = new Downloader(workingDirectory, model).huggingFaceModel();
    
        // Loads the quantized model and specified use of quantized memory
        AbstractModel m = ModelSupport.loadModel(localModelPath, DType.F32, DType.I8);
    
        var systemPrompt = "You are a helpful chatbot who writes short responses.";
    
        PromptContext ctx = m.prompt()
                            .addUserMessage(prompt)
                            .addSystemMessage(systemPrompt)
                            .build(); //build method will create a PromptContext, if model don't support prompt, a simple PromptContext object will be created
    
        System.out.println("Prompt: " + ctx.getPrompt() + "\n");
        // Generates a response to the prompt and prints it
        // The api allows for streaming or non-streaming responses
        // The response is generated with a temperature of 0.7 and a max token length of 256
        Generator.Response r = m.generateBuilder()
                .session(UUID.randomUUID()) //By default, UUID.randomUUID()
                .promptContext(ctx) // Required or use prompt(String text)
                .ntokens(256) //By default, 256
                .temperature(0.0f) //By default, 0.0f
                .onTokenWithTimings((s, aFloat) -> {}) //By default, (s, aFloat) -> {}, nothing
                .generate();
    
        System.out.println(r.responseText);
     }
    

    Devloping Jlama

    See DEVELOPER_GUIDE.md for more information.

    ⭐ Give us a Star!

    If you like or are using this project to build your own, please give us a star. It's a free way to show your support.

    🗺️ Roadmap

    • Support more and more models
    • Add pure java tokenizers
    • Support Quantization (e.g. k-quantization)
    • Add LoRA support
    • GraalVM support
    • Add distributed inference

    🏷️ License and Citation

    The code is available under Apache License.

    If you find this project helpful in your research, please cite this work at

    @misc{jlama2024,
        title = {Jlama: A modern Java inference engine for large language models},
        url = {https://github.com/tjake/jlama},
        author = {T Jake Luciani},
        month = {January},
        year = {2024}
    }