标签: Llama

  • 在纯Java文件中推理Llama 2

    在现代人工智能领域,推理大型语言模型(LLM)已经成为一个重要的应用场景。GitHub上的项目 mukel/llama2.java 提供了一种使用纯Java代码进行Llama 2推理的简洁实现。本文将详细介绍该项目的背景、构建方法及性能表现。

    背景介绍

    Llama 2是由Andrej Karpathy开发的一个非常简单的LLM推理实现。该项目的Java版本旨在提供教育价值,并用于在JVM上测试和调整编译器优化,特别是针对Graal编译器的优化。这一Java移植版本最初参考了llama2.scala。

    构建与运行

    要构建和运行该项目,您需要Java 21+,特别是其中的MemorySegment mmap-ing功能。以下是具体的构建步骤:

    1. 下载必要的文件: wget https://github.com/karpathy/llama2.c/raw/master/tokenizer.bin wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M. bin
    2. 手动构建与运行: javac --enable-preview -source 21 --add-modules=jdk.incubator.vector Llama2.java java --enable-preview --add-modules=jdk.incubator.vector Llama2 stories15M. bin
    3. 使用JBang直接运行: jbang Llama2.java stories15M. bin
    4. 使用Makefile和run.sh脚本: make # 可选,run.sh已经包含了make JAVA_HOME=$GRAALVM_HOME \ JAVA_RUNTIME_OPTIONS=-Djava.util.concurrent.ForkJoinPool.common.parallelism=8 \ ./run.sh stories15M. bin

    生成本地镜像

    使用GraalVM可以创建一个独立的本地镜像:

    JAVA_HOME=$GRAALVM_HOME NATIVE_IMAGE_OPTIONS="-march=native" make native-image
    ./llama2 stories15M. bin

    或者使用Profile-Guided Optimizations (PGO):

    JAVA_HOME=$GRAALVM_HOME \
    NATIVE_IMAGE_OPTIONS="--pgo-instrument -march=native --initialize-at-build-time=Llama2 -Dllama2.VectorAPI=false" \
    make native-image
    
    # 生成默认的iprof配置文件
    ./llama2 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 stories15M. bin
    
    # 构建优化后的镜像
    JAVA_HOME=$GRAALVM_HOME \
    NATIVE_IMAGE_OPTIONS="--pgo -march=native --initialize-at-build-time=Llama2 -Dllama2.VectorAPI=false" \
    make native-image
    
    # 优化后的运行速度应该比普通镜像快约2倍
    ./llama2 stories15M. bin

    性能表现

    以下是该项目在不同配置下的性能测试结果(基于AMD Ryzen 3950X 64GB,Arch Linux):

    单线程测试

    模型每秒处理Token相对于llama2.c的加速实现
    stories15M. bin3631.0llama2.c
    stories15M. bin2370.65llama2.java
    stories110M. bin51.711.0llama2.c
    stories110M. bin42.200.81llama2.java
    llama2_7B. bin0.921.0llama2.c
    llama2_7B. bin0.880.95llama2.java

    多线程测试

    模型每秒处理Token相对于llama2.c的加速实现
    stories15M. bin12331.0llama2.c
    stories15M. bin4380.35llama2.java
    stories110M. bin901.0llama2.c
    stories110M. bin800.88llama2.java
    llama2_7B. bin1.681.0llama2.c
    llama2_7B. bin1.650.98llama2.java

    需要注意的是,Java版本在多线程情况下的性能提升并不显著,这主要是由于内存带宽限制所致。

    结论

    mukel/llama2.java项目展示了如何使用纯Java代码实现Llama 2推理,并在一定程度上达到了与原始C实现相当的性能。尽管当前版本的性能尚未完全优化,但其作为教育工具和编译器优化测试平台已经展现出巨大潜力。

    参考文献:GitHub – mukel/llama2.java

  • 探索 Llama 3 在 Java 中的实际应用

    引言

    在现代人工智能领域,模型推理的效率和方便性是技术人员关注的核心问题。如今,我们将目光投向一个名为 Llama 3 的项目,该项目旨在在 Java 环境中实现 Llama 3 的推理。这一项目不仅是其前身 Llama2.java 的延续,还在多个方面进行了优化和改进。让我们深入了解这个项目的细节及其实现方法。

    项目背景

    Llama 3 是基于 Andrej Karpathy 的 llama2.c 项目的一个扩展版本。Llama3.java 通过单个 Java 文件实现了 Llama 3 的推理,除了教育价值外,还为在 JVM 上测试和调整编译器优化和功能提供了便利,特别是针对 Graal 编译器的优化。

    项目特点

    1. 单文件实现,无依赖

    Llama3.java 的一大特点是其实现是通过单个 Java 文件完成的。这种设计简化了项目的依赖管理,使得项目的部署和维护更加便捷。

    2. 支持多种量化格式

    项目支持 GGUF 格式解析,并且提供了对 Q8_0 和 Q4_0 量化的支持。Q4_0 量化模型由于其较小的体积和较高的运行效率,成为推荐使用的模型。

    3. 高效的矩阵-向量乘法

    针对量化张量,项目使用了 Java 的 Vector API 实现了快速的矩阵-向量乘法。这一实现提高了推理的运行速度,特别是在处理大规模数据时。

    4. 简单的命令行界面

    Llama3.java 提供了一个简单的命令行界面,支持 --chat--instruct 模式,使用户能够方便地与模型进行交互。

    项目设置与运行

    下载量化模型

    首先,需要从 Hugging Face 下载纯 Q4_0 和(可选的)Q8_0 量化的 .gguf 文件。推荐使用大约 4.3GB 的 Q4_0 量化模型:

    curl -L -O https://huggingface.co/mukel/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_0.gguf
    
    # 可选地下载 Q8_0 量化模型(约 8GB)
    # curl -L -O https://huggingface.co/mukel/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q8_0.gguf

    手动量化

    如果需要生成纯 Q4_0 量化模型,可以使用 llama.cpp 提供的量化工具从高精度的 .gguf 源文件生成:

    ./quantize --pure ./Meta-Llama-3-8B-Instruct-F32.gguf ./Meta-Llama-3-8B-Instruct-Q4_0.gguf Q4_0

    构建与运行

    Llama3.java 需要 Java 21 及以上版本,特别是 MemorySegment mmap-ing 功能。可以使用 jbang 工具运行:

    jbang Llama3.java --help

    或者直接执行:

    chmod +x Llama3.java
    ./Llama3.java --help

    使用 Makefile 手动构建

    项目提供了一个简单的 Makefile,可以运行 make 来生成 llama3.jar:

    javac -g --enable-preview -source 21 --add-modules jdk.incubator.vector -d target/classes Llama3.java
    jar -cvfe llama3.jar com.llama4j.Llama3 LICENSE -C target/classes .

    生成的 jar 文件可以如下运行:

    java --enable-preview --add-modules jdk.incubator.vector -jar llama3.jar --help

    性能评估

    在不同的硬件配置下,Llama3.java 的性能表现如下:

    笔记本电脑 Intel 13900H

    模型tokens/s实现
    Llama-3-8B-Instruct-Q4_0.gguf7.53llama.cpp
    Llama-3-8B-Instruct-Q4_0.gguf6.95llama3.java
    Llama-3-8B-Instruct-Q8_0.gguf5.16llama.cpp
    Llama-3-8B-Instruct-Q8_0.gguf4.02llama3.java

    工作站 AMD 3950X

    模型tokens/s实现
    Llama-3-8B-Instruct-Q4_0.gguf9.26llama.cpp
    Llama-3-8B-Instruct-Q4_0.gguf8.03llama3.java
    Llama-3-8B-Instruct-Q8_0.gguf5.79llama.cpp
    Llama-3-8B-Instruct-Q8_0.gguf4.92llama3.java

    结论

    Llama3.java 在 Java 环境中实现了高效的 Llama 3 模型推理,其单文件实现和简单的命令行界面使其具有很高的实用性。虽然在某些性能指标上与 llama.cpp 存在差距,但其在 Java 生态系统中的表现依然值得肯定。

    参考文献

人生梦想 - 关注前沿的计算机技术 acejoy.com