Transformers
Transformers (ONNX) 임베딩
TransformersEmbeddingModel은 선택한 sentence transformer를 사용해 문장 임베딩을 로컬에서 계산하는 EmbeddingModel 구현이에요. 어떤 HuggingFace 임베딩 모델이든 사용할 수 있고, ONNX 형식으로 직렬화된 사전 훈련 transformer 모델을 사용해요. 이 글에서는 모델을 ONNX로 직렬화하는 방법부터 자동 설정, 오류 해결까지 자세히 알아볼게요.
출처: 문서
본문
TransformersEmbeddingModel은 선택한 sentence transformer를 사용해 문장 임베딩을 로컬에서 계산하는 EmbeddingModel 구현이에요.
어떤 HuggingFace Embedding 모델이든 사용할 수 있어요.
Open Neural Network Exchange (ONNX) 형식으로 직렬화된 사전 훈련 transformer 모델을 사용해요.
Deep Java Library와 Microsoft ONNX Java Runtime 라이브러리를 적용해 Java에서 ONNX 모델을 실행하고 임베딩을 계산해요.
Prerequisites
Java에서 실행하기 위해서는 Tokenizer와 Transformer Model을 ONNX 형식으로 직렬화해야 해요.
Serialize with optimum-cli - 이를 빠르게 달성하는 한 가지 방법은 optimum-cli 명령줄 도구를 사용하는 것이에요. 다음 스니펫은 Python 가상 환경을 준비하고, 필요한 패키지를 설치하고, optimum-cli로 지정한 모델을 직렬화(즉 내보내기)해요:
python3 -m venv venv
source ./venv/bin/activate
(venv) pip install --upgrade pip
(venv) pip install optimum onnx onnxruntime sentence-transformers
(venv) optimum-cli export onnx --model sentence-transformers/all-MiniLM-L6-v2 onnx-output-folder
이 스니펫은 sentence-transformers/all-MiniLM-L6-v2 transformer를 onnx-output-folder 폴더로 내보내요. 이 폴더에는 임베딩 모델이 사용하는 tokenizer.json과 model.onnx 파일이 포함돼요.
all-MiniLM-L6-v2 대신 어떤 huggingface transformer 식별자나 직접 파일 경로를 선택할 수 있어요.
Auto-configuration
| __ | Spring AI 자동 설정과 스타터 모듈 아티팩트 이름에 큰 변경이 있었어요. 자세한 내용은 upgrade notes를 참고해주세요. |
|---|
Spring AI는 ONNX Transformer Embedding Model에 대한 Spring Boot 자동 설정을 제공해요. 활성화하려면 프로젝트의 Maven pom.xml 파일에 다음 의존성을 추가하세요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-transformers</artifactId>
</dependency>
또는 Gradle build.gradle 빌드 파일에 추가할 수도 있어요:
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-transformers'
}
| __ | 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을, 빌드 시스템에 저장소를 추가하려면 Artifact Repositories 섹션을 참고하세요. |
|---|
구성하려면 spring.ai.embedding.transformer.* 프로퍼티를 사용하세요.
예를 들어 intfloat/e5-small-v2 텍스트 임베딩 모델로 클라이언트를 구성하려면 application.properties 파일에 다음을 추가하세요:
spring.ai.embedding.transformer.onnx.model-uri=https://huggingface.co/intfloat/e5-small-v2/resolve/main/model.onnx
spring.ai.embedding.transformer.tokenizer.uri=https://huggingface.co/intfloat/e5-small-v2/raw/main/tokenizer.json
지원되는 프로퍼티의 전체 목록은 다음과 같아요:
Embedding Properties
| __ | 임베딩 자동 설정의 활성화/비활성화는 이제 프리픽스 spring.ai.model.embedding이 붙은 최상위 프로퍼티로 설정해요. 활성화하려면 spring.ai.model.embedding=transformers (기본값으로 활성화됨). 비활성화하려면 spring.ai.model.embedding=none (또는 transformers와 일치하지 않는 어떤 값). 이 변경은 여러 모델의 설정을 허용하기 위한 것이에요. |
|---|
| Property | Description | Default |
|---|---|---|
| spring.ai.embedding.transformer.enabled (제거됨, 더 이상 유효하지 않음) | Transformer Embedding 모델 활성화. | true |
| spring.ai.model.embedding | Transformer Embedding 모델 활성화. | transformers |
| spring.ai.embedding.transformer.tokenizer.uri | ONNX 엔진이 만든 사전 훈련 HuggingFaceTokenizer의 URI (예: tokenizer.json). | onnx/all-MiniLM-L6-v2/tokenizer.json |
| spring.ai.embedding.transformer.tokenizer.options | 'addSpecialTokens', 'modelMaxLength', 'truncation', 'padding', 'maxLength', 'stride', 'padToMultipleOf' 같은 HuggingFaceTokenizer 옵션. 기본값으로 폴백하려면 비워두세요. | empty |
| spring.ai.embedding.transformer.cache.enabled | 원격 Resource 캐싱 활성화. | true |
| spring.ai.embedding.transformer.cache.directory | ONNX 모델 같은 원격 리소스를 캐시할 디렉터리 경로 | ${java.io.tmpdir}/spring-ai-onnx-model |
| spring.ai.embedding.transformer.onnx.model-uri | 기존의 사전 훈련 ONNX 모델. | onnx/all-MiniLM-L6-v2/model.onnx |
| spring.ai.embedding.transformer.onnx.model-output-name | 임베딩 계산에 사용할 ONNX 모델의 출력 노드 이름. | last_hidden_state |
| spring.ai.embedding.transformer.onnx.gpu-device-id | 실행할 GPU 디바이스 ID. >= 0일 때만 적용돼요. 그 외에는 무시돼요. (onnxruntime_gpu 의존성 추가 필요) | -1 |
| spring.ai.embedding.transformer.metadata-mode | 임베딩 계산에 Documents 내용과 메타데이터의 어느 부분을 사용할지 지정해요. | NONE |
Errors and special cases
__ | Caused by: ai.onnxruntime.OrtException: Supplied array is ragged,.. 같은 오류가 보이면, application.properties에서 tokenizer padding도 활성화해야 해요:
spring.ai.embedding.transformer.tokenizer.options.padding=true
---|---
__ | The generative output names don't contain expected: last_hidden_state. Consider one of the available model outputs: token_embeddings, …. 같은 오류가 있으면, 모델에 맞는 올바른 값으로 모델 출력 이름을 설정해야 해요. 오류 메시지에 나열된 이름을 고려하세요. 예:
spring.ai.embedding.transformer.onnx.model-output-name=token_embeddings
---|---
| __ | ai.onnxruntime.OrtException: Error code - ORT_FAIL - message: Deserialize tensor onnx::MatMul_10319 failed.GetFileLength for ./model.onnx_data failed:Invalid fd was supplied: -1 같은 오류가 있으면, 모델이 2GB보다 커서 model.onnx와 model.onnx_data 두 파일로 직렬화됐다는 뜻이에요. model.onnx_data를 External Data라고 하며 model.onnx와 같은 디렉터리에 있어야 해요. 현재 유일한 해결 방법은 큰 model.onnx_data를 Boot 애플리케이션을 실행하는 폴더에 복사하는 것이에요. |
|---|
__ | ai.onnxruntime.OrtException: Error code - ORT_EP_FAIL - message: Failed to find CUDA shared provider 같은 오류가 있으면, GPU 매개변수 spring.ai.embedding.transformer.onnx.gpu-device-id를 사용하고 있는데 onnxruntime_gpu 의존성이 없다는 뜻이에요.
<dependency>
<groupId>com.microsoft.onnxruntime</groupId>
<artifactId>onnxruntime_gpu</artifactId>
</dependency>
CUDA 버전에 맞는 적절한 onnxruntime_gpu 버전을 선택하세요(ONNX Java Runtime). ---|---
Manual Configuration
Spring Boot를 사용하지 않는다면 Onnx Transformers Embedding Model을 수동으로 구성할 수 있어요. 이를 위해 프로젝트의 Maven pom.xml 파일에 spring-ai-transformers 의존성을 추가하세요:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers</artifactId>
</dependency>
| __ | 빌드 파일에 Spring AI BOM을 추가하려면 Dependency Management 섹션을 참고해주세요. |
|---|
그런 다음 새 TransformersEmbeddingModel 인스턴스를 만들고 setTokenizerResource(tokenizerJsonUri)와 setModelResource(modelOnnxUri) 메서드를 사용해 내보낸 tokenizer.json과 model.onnx 파일의 URI를 설정하세요. (classpath:, file: 또는 https: URI 스키마가 지원돼요).
모델을 명시적으로 설정하지 않으면 TransformersEmbeddingModel은 기본적으로 sentence-transformers/all-MiniLM-L6-v2를 사용해요:
| Dimensions | 384 |
|---|---|
| Avg. performance | 58.80 |
| Speed | 14200 sentences/sec |
| Size | 80MB |
다음 스니펫은 TransformersEmbeddingModel을 수동으로 사용하는 방법을 보여줘요:
TransformersEmbeddingModel embeddingModel = new TransformersEmbeddingModel();
// (optional) defaults to classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json
embeddingModel.setTokenizerResource("classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json");
// (optional) defaults to classpath:/onnx/all-MiniLM-L6-v2/model.onnx
embeddingModel.setModelResource("classpath:/onnx/all-MiniLM-L6-v2/model.onnx");
// (optional) defaults to ${java.io.tmpdir}/spring-ai-onnx-model
// Only the http/https resources are cached by default.
embeddingModel.setResourceCacheDirectory("/tmp/onnx-zoo");
// (optional) Set the tokenizer padding if you see an errors like:
// "ai.onnxruntime.OrtException: Supplied array is ragged, ..."
embeddingModel.setTokenizerOptions(Map.of("padding", "true"));
embeddingModel.afterPropertiesSet();
List<List<Double>> embeddings = this.embeddingModel.embed(List.of("Hello world", "World is big"));
| __ | TransformersEmbeddingModel 인스턴스를 수동으로 만들면, 프로퍼티를 설정한 뒤 클라이언트를 사용하기 전에 afterPropertiesSet() 메서드를 호출해야 해요. |
|---|
첫 번째 embed() 호출은 큰 ONNX 모델을 다운로드해 로컬 파일 시스템에 캐시해요. 따라서 첫 호출은 평소보다 오래 걸릴 수 있어요. ONNX 모델이 저장되는 로컬 폴더를 설정하려면 #setResourceCacheDirectory(<path>) 메서드를 사용하세요. 기본 캐시 폴더는 ${java.io.tmpdir}/spring-ai-onnx-model이에요.
TransformersEmbeddingModel을 Bean으로 만드는 것이 더 편리하고(권장되며) 좋아요. 그러면 afterPropertiesSet()을 수동으로 호출할 필요가 없어요.
@Bean
public EmbeddingModel embeddingModel() {
return new TransformersEmbeddingModel();
}