Add simple user interface
This commit is contained in:
parent
2aad09df7d
commit
f84714a726
@ -1 +1 @@
|
|||||||
[1751004438] warming up the model with an empty run
|
[1751008457] warming up the model with an empty run
|
||||||
|
97
pom.xml
97
pom.xml
@ -1,46 +1,61 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
<parent>
|
https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<groupId>org.springframework.boot</groupId>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
|
||||||
</parent>
|
|
||||||
<groupId>com.pablotj</groupId>
|
|
||||||
<artifactId>ia-chat-boot</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<name>ia-chat-boot</name>
|
|
||||||
<description>Project IA chat boot</description>
|
|
||||||
|
|
||||||
<properties>
|
<parent>
|
||||||
<java.version>17</java.version>
|
<groupId>org.springframework.boot</groupId>
|
||||||
</properties>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<groupId>com.pablotj</groupId>
|
||||||
<dependency>
|
<artifactId>ia-chat-boot</artifactId>
|
||||||
<groupId>de.kherud</groupId>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<artifactId>llama</artifactId>
|
<name>ia-chat-boot</name>
|
||||||
<version>3.4.1</version>
|
<description>Project IA chat boot</description>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
<properties>
|
||||||
<plugins>
|
<java.version>17</java.version>
|
||||||
<plugin>
|
</properties>
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<dependencies>
|
||||||
</plugin>
|
<!-- Spring Boot Web -->
|
||||||
</plugins>
|
<dependency>
|
||||||
</build>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Thymeleaf template engine -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- llama-java (IA offline) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.kherud</groupId>
|
||||||
|
<artifactId>llama</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Test support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,21 +1,35 @@
|
|||||||
package com.pablotj.ia.chat.boot;
|
package com.pablotj.ia.chat.boot;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
import java.util.ArrayList;
|
||||||
@RequestMapping("/chat")
|
import java.util.List;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/")
|
||||||
public class ChatController {
|
public class ChatController {
|
||||||
|
|
||||||
|
private final List<ChatMessage> messages = new ArrayList<>();
|
||||||
private final LlamaService llamaService;
|
private final LlamaService llamaService;
|
||||||
|
|
||||||
public ChatController(LlamaService llamaService) {
|
public ChatController(LlamaService llamaService) {
|
||||||
this.llamaService = llamaService;
|
this.llamaService = llamaService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping("/chat")
|
||||||
public String chat(@RequestParam String prompt) {
|
public String showChat(Model model) {
|
||||||
return llamaService.chat(prompt);
|
model.addAttribute("messages", messages);
|
||||||
|
return "chat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/chat")
|
||||||
|
public String handleChat(@RequestParam("prompt") String prompt, Model model) {
|
||||||
|
messages.add(new ChatMessage("user", prompt));
|
||||||
|
String reply = llamaService.chat(prompt);
|
||||||
|
messages.add(new ChatMessage("bot", reply));
|
||||||
|
model.addAttribute("messages", messages);
|
||||||
|
return "chat";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
src/main/java/com/pablotj/ia/chat/boot/ChatMessage.java
Normal file
19
src/main/java/com/pablotj/ia/chat/boot/ChatMessage.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.pablotj.ia.chat.boot;
|
||||||
|
|
||||||
|
public class ChatMessage {
|
||||||
|
private String role; // "user" o "bot"
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public ChatMessage(String role, String text) {
|
||||||
|
this.role = role;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,14 @@ public class LlamaService implements AutoCloseable {
|
|||||||
public void init() {
|
public void init() {
|
||||||
try {
|
try {
|
||||||
ModelParameters params = new ModelParameters()
|
ModelParameters params = new ModelParameters()
|
||||||
.setModelFilePath("models/openchat-3.5-0106.Q4_K_M.gguf");
|
.setModelFilePath("models/ggml-model-q3_k.gguf")
|
||||||
|
.setSeed(42)
|
||||||
|
.setNThreads(8) // usa 8 hilos CPU (ajusta según tu CPU)
|
||||||
|
.setNGpuLayers(0) // no usar GPU
|
||||||
|
.setMainGpu(-1) // deshabilitar GPU principal
|
||||||
|
.setNoKvOffload(true) // no descargar KV, evitar errores GPU
|
||||||
|
.setUseMmap(true) // mejorar gestión memoria
|
||||||
|
.setNPredict(128);
|
||||||
model = new LlamaModel(params);
|
model = new LlamaModel(params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Error cargando el modelo", e);
|
throw new RuntimeException("Error cargando el modelo", e);
|
||||||
@ -33,9 +40,11 @@ public class LlamaService implements AutoCloseable {
|
|||||||
String finalPrompt = chat.build();
|
String finalPrompt = chat.build();
|
||||||
|
|
||||||
InferenceParameters inf = new InferenceParameters(finalPrompt)
|
InferenceParameters inf = new InferenceParameters(finalPrompt)
|
||||||
.setTemperature(0.7f)
|
.setNPredict(200)
|
||||||
.setTopP(0.9f)
|
.setTemperature(0.7f)
|
||||||
.setTopK(40);
|
.setTopP(0.9f)
|
||||||
|
.setTopK(40)
|
||||||
|
.setUseChatTemplate(true);
|
||||||
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -13,21 +13,23 @@ public class PromptBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void user(String message) {
|
public void user(String message) {
|
||||||
turns.add("GPT4 Correct User: " + message + "<|end_of_turn|>");
|
turns.add("<|im_start|>user\n" + message + "\n<|im_end|>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assistant(String message) {
|
public void assistant(String message) {
|
||||||
turns.add("GPT4 Correct Assistant: " + message + "<|end_of_turn|>");
|
turns.add("<|im_start|>assistant\n" + message + "\n<|im_end|>");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String build() {
|
public String build() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(systemPrompt).append("<|end_of_turn|>\n");
|
sb.append("<|im_start|>system\n")
|
||||||
|
.append(systemPrompt)
|
||||||
|
.append("\n<|im_end|>\n");
|
||||||
for (String turn : turns) {
|
for (String turn : turns) {
|
||||||
sb.append(turn).append("\n");
|
sb.append(turn).append("\n");
|
||||||
}
|
}
|
||||||
// Deja el último turno preparado para que el modelo continúe como "Assistant"
|
// Deja listo para que el modelo continúe como assistant generando respuesta:
|
||||||
sb.append("GPT4 Correct Assistant: ");
|
sb.append("<|im_start|>assistant\n");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
28
src/main/resources/templates/chat.html
Normal file
28
src/main/resources/templates/chat.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" lang="es">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Chat con IA Offline</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: sans-serif; max-width: 800px; margin: 2rem auto; }
|
||||||
|
.bubble { margin-bottom: 1rem; }
|
||||||
|
.user { color: #003366; font-weight: bold; }
|
||||||
|
.bot { color: #006600; }
|
||||||
|
textarea { width: 100%; height: 4em; margin-top: 1rem; }
|
||||||
|
button { padding: 0.5rem 1rem; margin-top: 0.5rem; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Chat con IA Offline</h1>
|
||||||
|
|
||||||
|
<div th:each="msg : ${messages}" class="bubble">
|
||||||
|
<div th:if="${msg.role} == 'user'" class="user">🧑💻: <span th:text="${msg.text}"></span></div>
|
||||||
|
<div th:if="${msg.role} == 'bot'" class="bot">🤖: <span th:text="${msg.text}"></span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="post" th:action="@{/chat}">
|
||||||
|
<textarea name="prompt" placeholder="Escribe tu mensaje aquí..."></textarea><br>
|
||||||
|
<button type="submit">Enviar</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user