Skip to content

Commit

Permalink
Add support for BGE 1.5 (regular and quantized) in process embedding
Browse files Browse the repository at this point in the history
- Add the BGE 1.5 local embedding
- Update EasyRAG to exclude the dependency (it was a transitive dependency) but fix the dependency on the HuggingFace tokenizer
- Add integration tests to verify the regular and quantized model in JVM mode and native
- Add the new models to the in-process-embedding.adoc
  • Loading branch information
cescoffier authored and jmartisk committed Oct 3, 2024
1 parent afbdb98 commit 38f1f44
Show file tree
Hide file tree
Showing 18 changed files with 404 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,11 @@ record LocalEmbeddingModel(String classname, String modelName, String onnxModelP
"bge-small-en-q.onnx", "bge-small-en-q-tokenizer.json"),
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallen.BgeSmallEnEmbeddingModel", "bge-small-en",
"bge-small-en.onnx", "bge-small-en-tokenizer.json"),
// Add BGE 1.5 - on hold for now - see https://github.com/quarkiverse/quarkus-langchain4j/issues/897#issuecomment-2387691937
// new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel",
// "bge-small-en-v1.5-q", "bge-small-en-v1.5-q.onnx", "bge-small-en-v1.5-q-tokenizer.json"),
// new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel",
// "bge-small-en-v1.5",
// "bge-small-en-v1.5.onnx", "bge-small-en-v1.5-tokenizer.json"),
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel",
"bge-small-en-v1.5-q", "bge-small-en-v1.5-q.onnx", "bge-small-en-v1.5-q-tokenizer.json"),
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel",
"bge-small-en-v1.5",
"bge-small-en-v1.5.onnx", "bge-small-en-v1.5-tokenizer.json"),
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallzhq.BgeSmallZhQuantizedEmbeddingModel",
"bge-small-zh-q",
"bge-small-zh-q.onnx", "bge-small-zh-q-tokenizer.json"),
Expand Down
23 changes: 13 additions & 10 deletions docs/modules/ROOT/pages/in-process-embedding.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ To compute the _embedding_ of a document, you need to send the document to the r
In-process models avoids this overhead by running the model in the same process as the application.
This is generally faster, but requires more memory.

You can check the https://huggingface.co/spaces/mteb/leaderboard[MTEB (Massive Text Embedding Benchmark) leaderboard] to select the most appropriate model for your use case.

== Supported in-process models

The Quarkus LangChain4j extension provides supports for a set of in-process embedding models.
Expand All @@ -33,6 +35,17 @@ The following table lists the supported models, and the corresponding dependency
| 384
| `dev.langchain4j.model.embedding.onnx.allminilml6v2.AllMiniLmL6V2EmbeddingModel`

| https://huggingface.co/BAAI/bge-small-en-v1.5[bge-small-en-v1.5 (quantized)]
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-v15-q:{langchain4j-version}`
| 384
| `dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel`

| https://huggingface.co/BAAI/bge-small-en-v1.5[bge-small-en-v1.5]
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-v15:{langchain4j-version}`
| 384
| `dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel`


| https://huggingface.co/BAAI/bge-small-en[bge-small-en (quantized)]
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-q:{langchain4j-version}`
| 384
Expand Down Expand Up @@ -66,16 +79,6 @@ The following table lists the supported models, and the corresponding dependency

|===

Furthermore, when using these models, the following dependency should be added:

[source,xml]
----
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-parsers-base</artifactId>
</dependency>
----

== Injecting an embedding model

You can inject the model in your application using:
Expand Down
16 changes: 16 additions & 0 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-anthropic-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
Expand Down Expand Up @@ -174,6 +182,14 @@
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-mistral-ai-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-integration-tests-in-process-embedding-models</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<artifactId>quarkus-langchain4j-integration-test-embed-bge-small-en-v15-q</artifactId>
<name>Quarkus LangChain4j - Integration Tests - embeddings-bge-small-en-v15-q</name>

<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings-bge-small-en-v15-q</artifactId>
<version>${langchain4j-embeddings.version}</version>
</dependency>

<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-core</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devtools-testing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.acme.test;

import jakarta.inject.Inject;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;

import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel;

@Path("/in-process-embedding")
public class InProcessEmbeddingResource {

@Inject
BgeSmallEnV15QuantizedEmbeddingModel typedModel;

@Inject
EmbeddingModel embeddingModel;

@POST
public String computeEmbedding(String sentence) {
var r1 = typedModel.embed(sentence);
var r2 = embeddingModel.embed(sentence);

return "BgeSmallEnV15QuantizedEmbeddingModel: " + r1.content().dimension() + "\n" + "embeddingModel: "
+ r2.content().dimension();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#quarkus.native.additional-build-args=--trace-class-initialization=ai.onnxruntime.OnnxRuntime
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.acme.test;

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
class InProcessEmbeddingResourceIT extends InProcessEmbeddingResourceTest {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.acme.test;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;

@QuarkusTest
class InProcessEmbeddingResourceTest {

@Test
void test() {
var s = RestAssured.given()
.body("This is a sentence.")
.post("/in-process-embedding")
.andReturn().asString();
Assertions.assertThat(s)
.contains("BgeSmallEnV15QuantizedEmbeddingModel: 384\n" + "embeddingModel: 384");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-integration-tests-in-process-embedding-models</artifactId>
<version>999-SNAPSHOT</version>
</parent>

<artifactId>quarkus-langchain4j-integration-test-embed-bge-small-en-v15</artifactId>
<name>Quarkus LangChain4j - Integration Tests - embeddings-bge-small-en-v15</name>

<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings-bge-small-en-v15</artifactId>
<version>${langchain4j-embeddings.version}</version>
</dependency>

<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-core</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devtools-testing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${native.surefire.skip}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>
Loading

0 comments on commit 38f1f44

Please sign in to comment.