Development/Artificial Intelligence

Spring AI : Spring Boot와 대형 언어 모델(LLM)의 쉬운 연동 방법

Danny Seo 2024. 6. 23. 11:17

Spring AI, Spring Boot와 LLM의 연동 방법

 

안녕하세요, 저는 자바 백엔드 개발 엔지니어 devloo입니다. 대형 언어 모델(LLM)의 응용에 큰 관심을 가지고 있는 저는, 이번 AI의 봄을 맞아 여러분께 흥미로운 소식을 전하려고 합니다. 바로 Spring AI입니다. 이번 글에서는 Spring AI와 Ollama 로컬 모델을 어떻게 통합할 수 있는지 자세히 소개해 드리겠습니다. AI와 자바의 만남을 통해 새로운 가능성을 탐구해보세요.

Spring AI

Spring AI의 Spring Initializr에 등록

 

2024년 2월 29일에 공식적으로 Spring AI가 Spring Initializr에 등록되었습니다. 이는 AI와의 상호작용을 보다 간편하게 하여 자바 작업에 LLM 모델을 통합하는 학습 곡선을 줄여줍니다. 이제 start.spring.io에서 사용 및 구성이 가능합니다.

Spring AI는 인공지능 엔지니어링을 위한 애플리케이션 프레임워크입니다. 그 목적은 이식성과 모듈형 디자인과 같은 Spring 생태계의 디자인 원칙을 AI 분야에 적용하고, POJO를 AI 애플리케이션의 구성 요소로 사용하는 것을 촉진하는 것입니다.

기능

이식 가능한 API는 대화, 텍스트-이미지 및 임베딩 모델을 포함한 다양한 AI 제공자 간의 상호작용을 지원합니다. 동기 및 스트림 API 옵션을 지원하며 특정 모델에 접근하기 위한 매개변수 설정도 가능합니다.

지원되는 대화 모델:

  • OpenAI
  • Azure Open AI
  • Amazon Bedrock
  • Anthropic’s Claude
  • Cohere’s Command
  • AI21 Labs’ Jurassic-2
  • Meta’s LLama 2
  • Amazon’s Titan
  • Google Vertex AI
  • HuggingFace — Numerous models on HuggingFace, such as Llama2
  • Ollama — GPU 없이 로컬에서 AI 모델 실행 지원

지원되는 텍스트-이미지 모델:

  • OpenAI with DALL-E
  • StabilityAI

지원되는 벡터 모델:

  • OpenAI
  • Azure OpenAI
  • Ollama
  • ONNX
  • PostgresML
  • Bedrock Cohere
  • Bedrock Titan
  • Google VertexAI

공식 문서: spring.io/projects/spring-ai

빠른 시작

IDEA를 사용하여 필요한 AI 모델 의존성을 선택하여 새 프로젝트를 빠르게 시작하세요.

여기서는 Ollama 모델을 예로 들어보겠습니다 :

Spring AI의 모델 선택 방법

 

Ollama

Ollama는 GPU 자원 없이도 로컬 컴퓨터에서 단 한 번의 클릭으로 대형 모델을 구축할 수 있게 해주며, 콘솔 및 RestfulAPI를 제공하여 대형 모델을 빠르게 테스트하고 통합할 수 있습니다.

 

Ollama가 지원하는 모델:

Ollama 웹사이트: ollama.com/library

Ollama가 지원하는 모델

  • Gemma는 Google Meta에서 최근 출시한 모델입니다.
  • Llama2 모델은 중국어를 잘 지원하지 않지만, Gemma 모델은 중국어에 더 친숙합니다.

의존성 추가

팁: Spring AI와 관련된 의존성은 Maven 중앙 저장소에 없으므로 Spring의 저장소를 구성해야 합니다.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Ollama 모델 실행

로컬 컴퓨터 콘솔에서 ollama run gemma:2b 명령을 실행하세요 (여기서는 gemma 모델을 사용합니다).

Ollama 모델 실행

첫 실행 시 모델 파일을 다운로드합니다 (약 3GB, 시간이 걸릴 수 있음).

모델 리소스를 다운로드한 후 모델이 자동으로 시작되며, 콘솔에서 모델을 테스트하고 상호작용할 수 있습니다.

Ollama 모델 구성

이 프로젝트의 application.yml 구성 파일을 수정하여 다음을 추가합니다:

spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        model: gemma:2b

테스트

@Test
void contextLoads() {
    String message = """
                Who is Donald Trump?                               
            """;
    System.out.println(chatClient.call(message));
}

Ollama 모델의 Spring Boot 테스트

스트림 접근

@Test
void streamChat() throws ExecutionException, InterruptedException {
    // 비동기 함수를 만들어 테스트 함수를 수동으로 종료
    CompletableFuture<Void> future = new CompletableFuture<>();

    String message = """
            year-end work summary report
            """;
    PromptTemplate promptTemplate = new PromptTemplate("""
            You are a Java development engineer, and you are good at writing the company’s year-end work summary report.
            Write a 100-word summary report based on: {message} scenario
            """);
    Prompt prompt = promptTemplate.create(Map.of("message", message));
    chatClient.stream(prompt).subscribe(
            chatResponse -> {
                System.out.println("response: " + chatResponse.getResult().getOutput().getContent());
            },
            throwable -> {
                System.err.println("err: " + throwable.getMessage());
            },
            () -> {
                System.out.println("complete~!");
                // 함수 종료
                future.complete(null);
            }
    );
    future.get();
}

 

끝까지 읽어주셔서 정말 감사합니다.

 

혹시 궁금하신 사항이 있으면 댓글 남겨주세요 !!