Merged lm-lib
git-svn-id: svn://home0/lm-lib@3737 71dcc7fd-b1f2-4e5d-bb8e-274146e81173
This commit is contained in:
4
pom.xml
4
pom.xml
@@ -4,13 +4,13 @@
|
|||||||
<artifactId>lm-lib</artifactId>
|
<artifactId>lm-lib</artifactId>
|
||||||
<groupId>de.extio</groupId>
|
<groupId>de.extio</groupId>
|
||||||
<name>lm-lib</name>
|
<name>lm-lib</name>
|
||||||
<version>1.1.0</version>
|
<version>1.3.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<spring-boot.version>3.4.2</spring-boot.version>
|
<spring-boot.version>3.4.4</spring-boot.version>
|
||||||
<azureai.version>1.0.0-beta.2</azureai.version>
|
<azureai.version>1.0.0-beta.2</azureai.version>
|
||||||
<jtokkit.version>1.1.0</jtokkit.version>
|
<jtokkit.version>1.1.0</jtokkit.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import de.extio.lmlib.client.cached.CachedClient;
|
import de.extio.lmlib.client.cached.CachedClient;
|
||||||
import de.extio.lmlib.client.cached.CachedClientRepository;
|
import de.extio.lmlib.client.cached.CachedClientRepository;
|
||||||
import de.extio.lmlib.profile.ModelCategory;
|
import de.extio.lmlib.profile.ModelCategory;
|
||||||
|
import de.extio.lmlib.profile.ModelProfile.ModelProvider;
|
||||||
import de.extio.lmlib.profile.ModelProfileService;
|
import de.extio.lmlib.profile.ModelProfileService;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -23,6 +24,9 @@ public class ClientService {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private CachedClientRepository cachedClientRepository;
|
private CachedClientRepository cachedClientRepository;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<CompletionInterceptor> completionInterceptors;
|
||||||
|
|
||||||
@Cacheable("clients")
|
@Cacheable("clients")
|
||||||
public Client getClient(final ModelCategory category) {
|
public Client getClient(final ModelCategory category) {
|
||||||
final var modelProfile = this.modelProfileService.getModelProfile(category.getModelProfile());
|
final var modelProfile = this.modelProfileService.getModelProfile(category.getModelProfile());
|
||||||
@@ -30,7 +34,44 @@ public class ClientService {
|
|||||||
.filter(client -> client.getModelProvider() == modelProfile.modelProvider())
|
.filter(client -> client.getModelProvider() == modelProfile.modelProvider())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(client -> this.cachedClientRepository == null ? client : new CachedClient(this.cachedClientRepository, this.modelProfileService, client))
|
.map(client -> this.cachedClientRepository == null ? client : new CachedClient(this.cachedClientRepository, this.modelProfileService, client))
|
||||||
|
.map(client -> this.completionInterceptors == null || this.completionInterceptors.isEmpty() ? client : new InterceptingClient(client, this.completionInterceptors))
|
||||||
.orElseThrow(() -> new IllegalStateException("No client found for model profile " + category));
|
.orElseThrow(() -> new IllegalStateException("No client found for model profile " + category));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class InterceptingClient implements Client {
|
||||||
|
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
private final List<CompletionInterceptor> completionInterceptors;
|
||||||
|
|
||||||
|
public InterceptingClient(final Client client, final List<CompletionInterceptor> completionInterceptors) {
|
||||||
|
this.client = client;
|
||||||
|
this.completionInterceptors = completionInterceptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Completion completion(final ModelCategory modelCategory, final String system, final String question, final String fullText) {
|
||||||
|
return this.client.completion(modelCategory, system, question, fullText);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Completion conversation(final ModelCategory modelCategory, final Conversation conversation_) {
|
||||||
|
Conversation conversation = conversation_;
|
||||||
|
for (final var interceptor : this.completionInterceptors) {
|
||||||
|
conversation = interceptor.before(modelCategory, conversation);
|
||||||
|
}
|
||||||
|
var completion = this.client.conversation(modelCategory, conversation);
|
||||||
|
for (final var interceptor : this.completionInterceptors) {
|
||||||
|
completion = interceptor.after(modelCategory, completion);
|
||||||
|
}
|
||||||
|
return completion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelProvider getModelProvider() {
|
||||||
|
return this.client.getModelProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.extio.lmlib.client;
|
||||||
|
|
||||||
|
import de.extio.lmlib.profile.ModelCategory;
|
||||||
|
|
||||||
|
public interface CompletionInterceptor {
|
||||||
|
|
||||||
|
Conversation before(ModelCategory modelCategory, Conversation conversation);
|
||||||
|
|
||||||
|
Completion after(ModelCategory modelCategory, Completion completion);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package de.extio.lmlib.prompt;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class Llama4PromptStrategy implements PromptStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuilder start(final String system, final String question, final String text) {
|
||||||
|
final StringBuilder prompt = new StringBuilder();
|
||||||
|
prompt.append("<|begin_of_text|>");
|
||||||
|
if (!system.isEmpty()) {
|
||||||
|
prompt.append("<|header_start|>system<|header_end|>\n\n");
|
||||||
|
prompt.append(system);
|
||||||
|
prompt.append("<|eot|>");
|
||||||
|
}
|
||||||
|
prompt.append("<|header_start|>user<|header_end|>\n\n");
|
||||||
|
prompt.append(question);
|
||||||
|
if (!question.isEmpty() && !text.isEmpty()) {
|
||||||
|
prompt.append("\n\n");
|
||||||
|
}
|
||||||
|
prompt.append(text);
|
||||||
|
prompt.append("<|eot|><|header_start|>assistant<|header_end|>\n");
|
||||||
|
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void continue_(final StringBuilder prompt, final String assistant) {
|
||||||
|
this.next(prompt, assistant, "Continue");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void next(final StringBuilder prompt, final String assistant, final String user) {
|
||||||
|
prompt.append(assistant);
|
||||||
|
prompt.append("<|eot|><|header_start|>user<|header_end|>\n\n" + user + "<|eot|><|header_start|>assistant<|header_end|>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String removeEOT(final String prompt) {
|
||||||
|
return prompt.strip().replace("<|eot|>", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPromptName() {
|
||||||
|
return "llama4";
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user