Skip to content

Commit 38f1f44

Browse files
cescoffierjmartisk
authored andcommitted
Add support for BGE 1.5 (regular and quantized) in process embedding
- 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
1 parent afbdb98 commit 38f1f44

File tree

18 files changed

+404
-24
lines changed

18 files changed

+404
-24
lines changed

core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/InProcessEmbeddingProcessor.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ record LocalEmbeddingModel(String classname, String modelName, String onnxModelP
4747
"bge-small-en-q.onnx", "bge-small-en-q-tokenizer.json"),
4848
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallen.BgeSmallEnEmbeddingModel", "bge-small-en",
4949
"bge-small-en.onnx", "bge-small-en-tokenizer.json"),
50-
// Add BGE 1.5 - on hold for now - see https://github.com/quarkiverse/quarkus-langchain4j/issues/897#issuecomment-2387691937
51-
// new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel",
52-
// "bge-small-en-v1.5-q", "bge-small-en-v1.5-q.onnx", "bge-small-en-v1.5-q-tokenizer.json"),
53-
// new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel",
54-
// "bge-small-en-v1.5",
55-
// "bge-small-en-v1.5.onnx", "bge-small-en-v1.5-tokenizer.json"),
50+
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel",
51+
"bge-small-en-v1.5-q", "bge-small-en-v1.5-q.onnx", "bge-small-en-v1.5-q-tokenizer.json"),
52+
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel",
53+
"bge-small-en-v1.5",
54+
"bge-small-en-v1.5.onnx", "bge-small-en-v1.5-tokenizer.json"),
5655
new LocalEmbeddingModel("dev.langchain4j.model.embedding.onnx.bgesmallzhq.BgeSmallZhQuantizedEmbeddingModel",
5756
"bge-small-zh-q",
5857
"bge-small-zh-q.onnx", "bge-small-zh-q-tokenizer.json"),

docs/modules/ROOT/pages/in-process-embedding.adoc

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ To compute the _embedding_ of a document, you need to send the document to the r
1212
In-process models avoids this overhead by running the model in the same process as the application.
1313
This is generally faster, but requires more memory.
1414

15+
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.
16+
1517
== Supported in-process models
1618

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

38+
| https://huggingface.co/BAAI/bge-small-en-v1.5[bge-small-en-v1.5 (quantized)]
39+
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-v15-q:{langchain4j-version}`
40+
| 384
41+
| `dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel`
42+
43+
| https://huggingface.co/BAAI/bge-small-en-v1.5[bge-small-en-v1.5]
44+
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-v15:{langchain4j-version}`
45+
| 384
46+
| `dev.langchain4j.model.embedding.onnx.bgesmallenv15.BgeSmallEnV15EmbeddingModel`
47+
48+
3649
| https://huggingface.co/BAAI/bge-small-en[bge-small-en (quantized)]
3750
|`dev.langchain4j:langchain4j-embeddings-bge-small-en-q:{langchain4j-version}`
3851
| 384
@@ -66,16 +79,6 @@ The following table lists the supported models, and the corresponding dependency
6679

6780
|===
6881

69-
Furthermore, when using these models, the following dependency should be added:
70-
71-
[source,xml]
72-
----
73-
<dependency>
74-
<groupId>io.quarkiverse.langchain4j</groupId>
75-
<artifactId>quarkus-langchain4j-parsers-base</artifactId>
76-
</dependency>
77-
----
78-
7982
== Injecting an embedding model
8083

8184
You can inject the model in your application using:

docs/pom.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@
104104
<groupId>io.quarkiverse.langchain4j</groupId>
105105
<artifactId>quarkus-langchain4j-anthropic-deployment</artifactId>
106106
<version>${project.version}</version>
107+
<type>pom</type>
108+
<scope>test</scope>
109+
<exclusions>
110+
<exclusion>
111+
<groupId>*</groupId>
112+
<artifactId>*</artifactId>
113+
</exclusion>
114+
</exclusions>
107115
</dependency>
108116
<dependency>
109117
<groupId>io.quarkiverse.langchain4j</groupId>
@@ -174,6 +182,14 @@
174182
<groupId>io.quarkiverse.langchain4j</groupId>
175183
<artifactId>quarkus-langchain4j-mistral-ai-deployment</artifactId>
176184
<version>${project.version}</version>
185+
<type>pom</type>
186+
<scope>test</scope>
187+
<exclusions>
188+
<exclusion>
189+
<groupId>*</groupId>
190+
<artifactId>*</artifactId>
191+
</exclusion>
192+
</exclusions>
177193
</dependency>
178194
<dependency>
179195
<groupId>io.quarkiverse.langchain4j</groupId>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>io.quarkiverse.langchain4j</groupId>
7+
<artifactId>quarkus-langchain4j-integration-tests-in-process-embedding-models</artifactId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>quarkus-langchain4j-integration-test-embed-bge-small-en-v15-q</artifactId>
12+
<name>Quarkus LangChain4j - Integration Tests - embeddings-bge-small-en-v15-q</name>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>dev.langchain4j</groupId>
17+
<artifactId>langchain4j-embeddings-bge-small-en-v15-q</artifactId>
18+
<version>${langchain4j-embeddings.version}</version>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>io.quarkiverse.langchain4j</groupId>
23+
<artifactId>quarkus-langchain4j-core</artifactId>
24+
<version>${project.version}</version>
25+
</dependency>
26+
27+
<dependency>
28+
<groupId>io.quarkus</groupId>
29+
<artifactId>quarkus-rest-jackson</artifactId>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>io.quarkus</groupId>
34+
<artifactId>quarkus-junit5</artifactId>
35+
<scope>test</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>io.rest-assured</groupId>
39+
<artifactId>rest-assured</artifactId>
40+
<scope>test</scope>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.assertj</groupId>
44+
<artifactId>assertj-core</artifactId>
45+
<version>${assertj.version}</version>
46+
<scope>test</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>io.quarkus</groupId>
50+
<artifactId>quarkus-devtools-testing</artifactId>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>io.quarkus</groupId>
58+
<artifactId>quarkus-maven-plugin</artifactId>
59+
<executions>
60+
<execution>
61+
<goals>
62+
<goal>build</goal>
63+
</goals>
64+
</execution>
65+
</executions>
66+
</plugin>
67+
<plugin>
68+
<artifactId>maven-failsafe-plugin</artifactId>
69+
<executions>
70+
<execution>
71+
<goals>
72+
<goal>integration-test</goal>
73+
<goal>verify</goal>
74+
</goals>
75+
<configuration>
76+
<systemPropertyVariables>
77+
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
78+
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
79+
<maven.home>${maven.home}</maven.home>
80+
</systemPropertyVariables>
81+
</configuration>
82+
</execution>
83+
</executions>
84+
</plugin>
85+
</plugins>
86+
</build>
87+
<profiles>
88+
<profile>
89+
<id>native-image</id>
90+
<activation>
91+
<property>
92+
<name>native</name>
93+
</property>
94+
</activation>
95+
<build>
96+
<plugins>
97+
<plugin>
98+
<artifactId>maven-surefire-plugin</artifactId>
99+
<configuration>
100+
<skipTests>${native.surefire.skip}</skipTests>
101+
</configuration>
102+
</plugin>
103+
</plugins>
104+
</build>
105+
<properties>
106+
<skipITs>false</skipITs>
107+
<quarkus.package.type>native</quarkus.package.type>
108+
</properties>
109+
</profile>
110+
</profiles>
111+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.acme.test;
2+
3+
import jakarta.inject.Inject;
4+
import jakarta.ws.rs.POST;
5+
import jakarta.ws.rs.Path;
6+
7+
import dev.langchain4j.model.embedding.EmbeddingModel;
8+
import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel;
9+
10+
@Path("/in-process-embedding")
11+
public class InProcessEmbeddingResource {
12+
13+
@Inject
14+
BgeSmallEnV15QuantizedEmbeddingModel typedModel;
15+
16+
@Inject
17+
EmbeddingModel embeddingModel;
18+
19+
@POST
20+
public String computeEmbedding(String sentence) {
21+
var r1 = typedModel.embed(sentence);
22+
var r2 = embeddingModel.embed(sentence);
23+
24+
return "BgeSmallEnV15QuantizedEmbeddingModel: " + r1.content().dimension() + "\n" + "embeddingModel: "
25+
+ r2.content().dimension();
26+
}
27+
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#quarkus.native.additional-build-args=--trace-class-initialization=ai.onnxruntime.OnnxRuntime
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.acme.test;
2+
3+
import io.quarkus.test.junit.QuarkusIntegrationTest;
4+
5+
@QuarkusIntegrationTest
6+
class InProcessEmbeddingResourceIT extends InProcessEmbeddingResourceTest {
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.acme.test;
2+
3+
import org.assertj.core.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
6+
import io.quarkus.test.junit.QuarkusTest;
7+
import io.restassured.RestAssured;
8+
9+
@QuarkusTest
10+
class InProcessEmbeddingResourceTest {
11+
12+
@Test
13+
void test() {
14+
var s = RestAssured.given()
15+
.body("This is a sentence.")
16+
.post("/in-process-embedding")
17+
.andReturn().asString();
18+
Assertions.assertThat(s)
19+
.contains("BgeSmallEnV15QuantizedEmbeddingModel: 384\n" + "embeddingModel: 384");
20+
}
21+
22+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<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">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>io.quarkiverse.langchain4j</groupId>
7+
<artifactId>quarkus-langchain4j-integration-tests-in-process-embedding-models</artifactId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>quarkus-langchain4j-integration-test-embed-bge-small-en-v15</artifactId>
12+
<name>Quarkus LangChain4j - Integration Tests - embeddings-bge-small-en-v15</name>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>dev.langchain4j</groupId>
17+
<artifactId>langchain4j-embeddings-bge-small-en-v15</artifactId>
18+
<version>${langchain4j-embeddings.version}</version>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>io.quarkiverse.langchain4j</groupId>
23+
<artifactId>quarkus-langchain4j-core</artifactId>
24+
<version>${project.version}</version>
25+
</dependency>
26+
27+
<dependency>
28+
<groupId>io.quarkus</groupId>
29+
<artifactId>quarkus-rest-jackson</artifactId>
30+
</dependency>
31+
32+
<dependency>
33+
<groupId>io.quarkus</groupId>
34+
<artifactId>quarkus-junit5</artifactId>
35+
<scope>test</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>io.rest-assured</groupId>
39+
<artifactId>rest-assured</artifactId>
40+
<scope>test</scope>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.assertj</groupId>
44+
<artifactId>assertj-core</artifactId>
45+
<version>${assertj.version}</version>
46+
<scope>test</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>io.quarkus</groupId>
50+
<artifactId>quarkus-devtools-testing</artifactId>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>io.quarkus</groupId>
58+
<artifactId>quarkus-maven-plugin</artifactId>
59+
<executions>
60+
<execution>
61+
<goals>
62+
<goal>build</goal>
63+
</goals>
64+
</execution>
65+
</executions>
66+
</plugin>
67+
<plugin>
68+
<artifactId>maven-failsafe-plugin</artifactId>
69+
<executions>
70+
<execution>
71+
<goals>
72+
<goal>integration-test</goal>
73+
<goal>verify</goal>
74+
</goals>
75+
<configuration>
76+
<systemPropertyVariables>
77+
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
78+
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
79+
<maven.home>${maven.home}</maven.home>
80+
</systemPropertyVariables>
81+
</configuration>
82+
</execution>
83+
</executions>
84+
</plugin>
85+
</plugins>
86+
</build>
87+
<profiles>
88+
<profile>
89+
<id>native-image</id>
90+
<activation>
91+
<property>
92+
<name>native</name>
93+
</property>
94+
</activation>
95+
<build>
96+
<plugins>
97+
<plugin>
98+
<artifactId>maven-surefire-plugin</artifactId>
99+
<configuration>
100+
<skipTests>${native.surefire.skip}</skipTests>
101+
</configuration>
102+
</plugin>
103+
</plugins>
104+
</build>
105+
<properties>
106+
<skipITs>false</skipITs>
107+
<quarkus.package.type>native</quarkus.package.type>
108+
</properties>
109+
</profile>
110+
</profiles>
111+
</project>

0 commit comments

Comments
 (0)