-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jlama-sentiment added -> thank you for attending airhacks.live
- Loading branch information
Showing
11 changed files
with
300 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
models/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Models are located in the `models` directory and will be automatically downloaded. | ||
The model files are larger than 1GB. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?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> | ||
<groupId>airhacks</groupId> | ||
<artifactId>jlama-sentiment</artifactId> | ||
<version>0.0.1-SNAPSHOT</version> | ||
<packaging>jar</packaging> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<version>3.7.1</version> | ||
<configuration> | ||
<finalName>sentimental</finalName> | ||
<appendAssemblyId>false</appendAssemblyId> | ||
<archive> | ||
<manifest> | ||
<addClasspath>true</addClasspath> | ||
<mainClass>airhacks.App</mainClass> | ||
</manifest> | ||
</archive> | ||
<descriptorRefs> | ||
<descriptorRef>jar-with-dependencies</descriptorRef> | ||
</descriptorRefs> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>package-everything</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>single</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<version>3.5.1</version> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.github.tjake</groupId> | ||
<artifactId>jlama-core</artifactId> | ||
<version>0.8.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.github.tjake</groupId> | ||
<artifactId>jlama-native</artifactId> | ||
<version>0.8.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-nop</artifactId> | ||
<version>2.0.16</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter</artifactId> | ||
<version>5.11.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<version>3.26.3</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>21</maven.compiler.source> | ||
<maven.compiler.target>21</maven.compiler.target> | ||
<java.version>21</java.version> | ||
</properties> | ||
</project> |
16 changes: 16 additions & 0 deletions
16
samples/jlama-sentiment-v2/src/main/java/airhacks/App.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package airhacks; | ||
|
||
import airhacks.sentimental.boundary.SentimentAnalysis; | ||
|
||
/** | ||
* | ||
* @author airhacks.com | ||
*/ | ||
interface App { | ||
|
||
static void main(String... args) { | ||
var message = args.length > 0 ? args[0]: "java is great"; | ||
var result = SentimentAnalysis.analyze(message); | ||
System.out.println(result); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
samples/jlama-sentiment-v2/src/main/java/airhacks/logging/control/Log.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package airhacks.logging.control; | ||
|
||
public interface Log { | ||
|
||
public static void info(String message){ | ||
System.out.println(message); | ||
} | ||
|
||
public static void info(Object message){ | ||
info(message.toString()); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
...les/jlama-sentiment-v2/src/main/java/airhacks/sentimental/boundary/SentimentAnalysis.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package airhacks.sentimental.boundary; | ||
|
||
import java.io.IOException; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.util.UUID; | ||
|
||
import airhacks.logging.control.Log; | ||
import airhacks.sentimental.control.ModelLoader; | ||
import airhacks.sentimental.entity.Result; | ||
|
||
public interface SentimentAnalysis { | ||
|
||
String systemPrompt = """ | ||
Your task is to analyze whether a given statement is positive or negative. | ||
Only respond with either: "positive", "negative" or "neutral". | ||
Analyze the following statement: | ||
"""; | ||
|
||
static String invoke(String message) throws IOException { | ||
var model = ModelLoader.load(); | ||
var promptContext = model.promptSupport() | ||
.get() | ||
.builder() | ||
.addSystemMessage(systemPrompt) | ||
.addUserMessage(message) | ||
.build(); | ||
|
||
var response = model.generate(UUID.randomUUID(), promptContext, 0.0f, 256, (s, f) -> {}); | ||
var duration = response.promptTimeMs; | ||
Log.info("responded in: %d ms".formatted(duration)); | ||
return response.responseText; | ||
} | ||
|
||
public static Result analyze(String message){ | ||
var start = Instant.now(); | ||
String response; | ||
try { | ||
response = invoke(message); | ||
|
||
} catch (IOException e) { | ||
throw new RuntimeException("cannot invoke model. Reason: " + e); | ||
} | ||
var duration = Duration.between(start, Instant.now()); | ||
return Result.fromLLMResponse(duration,response); | ||
} | ||
|
||
|
||
} |
38 changes: 38 additions & 0 deletions
38
samples/jlama-sentiment-v2/src/main/java/airhacks/sentimental/control/ModelLoader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package airhacks.sentimental.control; | ||
|
||
import java.io.IOException; | ||
|
||
import com.github.tjake.jlama.model.AbstractModel; | ||
import com.github.tjake.jlama.model.ModelSupport; | ||
import com.github.tjake.jlama.safetensors.DType; | ||
import com.github.tjake.jlama.safetensors.SafeTensorSupport; | ||
|
||
public interface ModelLoader { | ||
enum Model{ | ||
TINY("tjake/TinyLlama-1.1B-Chat-v1.0-Jlama-Q4"), | ||
MISTRAL7B("tjake/Mistral-7B-Instruct-v0.3-JQ4"), | ||
MIXTRAL("tjake/Mixtral-8x7B-Instruct-v0.1-JQ4"), | ||
LLAMA("tjake/Llama-3.2-1B-Instruct-Jlama-Q4"); | ||
|
||
final String modelName; | ||
|
||
private Model(String modelName) { | ||
this.modelName = modelName; | ||
} | ||
|
||
public String modelName(){ | ||
return this.modelName; | ||
} | ||
|
||
|
||
} | ||
String workingDirectory = "./models"; | ||
|
||
|
||
static AbstractModel load() throws IOException{ | ||
var localModelPath = SafeTensorSupport | ||
.maybeDownloadModel(workingDirectory, Model.LLAMA.modelName()); | ||
return ModelSupport.loadModel(localModelPath, DType.F32, DType.I8); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
.../jlama-sentiment-v2/src/main/java/airhacks/sentimental/entity/HallucinationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package airhacks.sentimental.entity; | ||
|
||
public class HallucinationException extends IllegalStateException{ | ||
|
||
public HallucinationException(String response) { | ||
super("unexpected: " + response); | ||
} | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
samples/jlama-sentiment-v2/src/main/java/airhacks/sentimental/entity/Result.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package airhacks.sentimental.entity; | ||
|
||
import java.time.Duration; | ||
|
||
public record Result(Duration duration,Sentiment sentiment) { | ||
public enum Sentiment { | ||
POSITIVE, NEGATIVE, NEUTRAL; | ||
} | ||
|
||
public static Result fromLLMResponse(Duration duration,String answer) { | ||
var normalized = answer | ||
.trim() | ||
.toUpperCase(); | ||
try{ | ||
var sentiment = Sentiment.valueOf(normalized); | ||
return new Result(duration,sentiment); | ||
}catch(IllegalArgumentException ex){ | ||
throw new HallucinationException(answer); | ||
} | ||
} | ||
|
||
public boolean isPositive(){ | ||
return Sentiment.POSITIVE.equals(this.sentiment); | ||
} | ||
|
||
public boolean isNegative(){ | ||
return Sentiment.NEGATIVE.equals(this.sentiment); | ||
} | ||
|
||
public boolean isNeutral(){ | ||
return Sentiment.NEUTRAL.equals(this.sentiment); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...jlama-sentiment-v2/src/test/java/airhacks/sentimental/boundary/SentimentAnalysisTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package airhacks.sentimental.boundary; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.io.IOException; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import airhacks.logging.control.Log; | ||
|
||
public class SentimentAnalysisTest { | ||
|
||
@Test | ||
void analyze() throws IOException { | ||
var result = SentimentAnalysis.analyze("java is hot and tastes really good"); | ||
Log.info(result); | ||
assertThat(result.isPositive()).isTrue(); | ||
|
||
result = SentimentAnalysis.analyze("python is dangerous, unpredictable and slow"); | ||
Log.info(result); | ||
assertThat(result.isNegative()).isTrue(); | ||
|
||
result = SentimentAnalysis.analyze("old rusty engine"); | ||
Log.info(result); | ||
assertThat(result.isNegative()).isTrue(); | ||
|
||
result = SentimentAnalysis.analyze("where should I GO?"); | ||
Log.info(result); | ||
assertThat(result.isNeutral()).isTrue(); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
samples/jlama-sentiment-v2/src/test/java/airhacks/sentimental/entity/ResultTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package airhacks.sentimental.entity; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
public class ResultTest { | ||
@Test | ||
void hallucination() { | ||
var exception = assertThrows(HallucinationException.class, ()-> Result.fromLLMResponse(null, "incredible")); | ||
assertThat(exception).hasMessageContaining("incredible"); | ||
|
||
} | ||
|
||
@Test | ||
void positive() { | ||
var result = Result.fromLLMResponse(null, "positive"); | ||
assertThat(result.isPositive()).isTrue(); | ||
|
||
} | ||
|
||
@Test | ||
void negative() { | ||
var result = Result.fromLLMResponse(null, "negative"); | ||
assertThat(result.isNegative()).isTrue(); | ||
} | ||
} |