1
- using LLama . Abstractions ;
2
- using LLama . Common ;
1
+ using LLama . Common ;
2
+ using LLama . Transformers ;
3
3
4
4
namespace LLama . Examples . Examples ;
5
5
6
- // When using chatsession, it's a common case that you want to strip the role names
7
- // rather than display them. This example shows how to use transforms to strip them.
6
+ /// <summary>
7
+ /// This sample shows a simple chatbot
8
+ /// It's configured to use the default prompt template as provided by llama.cpp and supports
9
+ /// models such as llama3, llama2, phi3, qwen1.5, etc.
10
+ /// </summary>
8
11
public class LLama3ChatSession
9
12
{
10
13
public static async Task Run ( )
11
14
{
12
- string modelPath = UserSettings . GetModelPath ( ) ;
13
-
15
+ var modelPath = UserSettings . GetModelPath ( ) ;
14
16
var parameters = new ModelParams ( modelPath )
15
17
{
16
18
Seed = 1337 ,
17
19
GpuLayerCount = 10
18
20
} ;
21
+
19
22
using var model = LLamaWeights . LoadFromFile ( parameters ) ;
20
23
using var context = model . CreateContext ( parameters ) ;
21
24
var executor = new InteractiveExecutor ( context ) ;
22
25
23
26
var chatHistoryJson = File . ReadAllText ( "Assets/chat-with-bob.json" ) ;
24
- ChatHistory chatHistory = ChatHistory . FromJson ( chatHistoryJson ) ?? new ChatHistory ( ) ;
27
+ var chatHistory = ChatHistory . FromJson ( chatHistoryJson ) ?? new ChatHistory ( ) ;
25
28
26
29
ChatSession session = new ( executor , chatHistory ) ;
27
- session . WithHistoryTransform ( new LLama3HistoryTransform ( ) ) ;
30
+
31
+ // add the default templator. If llama.cpp doesn't support the template by default,
32
+ // you'll need to write your own transformer to format the prompt correctly
33
+ session . WithHistoryTransform ( new PromptTemplateTransformer ( model , withAssistant : true ) ) ;
34
+
35
+ // Add a transformer to eliminate printing the end of turn tokens, llama 3 specifically has an odd LF that gets printed sometimes
28
36
session . WithOutputTransform ( new LLamaTransforms . KeywordTextOutputStreamTransform (
29
- new string [ ] { "User:" , "Assistant:" , "�" } ,
37
+ [ model . Tokens . EndOfTurnToken ! , "�" ] ,
30
38
redundancyLength : 5 ) ) ;
31
39
32
- InferenceParams inferenceParams = new InferenceParams ( )
40
+ var inferenceParams = new InferenceParams ( )
33
41
{
42
+ MaxTokens = - 1 , // keep generating tokens until the anti prompt is encountered
34
43
Temperature = 0.6f ,
35
- AntiPrompts = new List < string > { "User:" }
44
+ AntiPrompts = [ model . Tokens . EndOfTurnToken ! ] // model specific end of turn string
36
45
} ;
37
46
38
47
Console . ForegroundColor = ConsoleColor . Yellow ;
39
48
Console . WriteLine ( "The chat session has started." ) ;
40
49
41
50
// show the prompt
42
51
Console . ForegroundColor = ConsoleColor . Green ;
43
- string userInput = Console . ReadLine ( ) ?? "" ;
52
+ Console . Write ( "User> " ) ;
53
+ var userInput = Console . ReadLine ( ) ?? "" ;
44
54
45
55
while ( userInput != "exit" )
46
56
{
57
+ Console . ForegroundColor = ConsoleColor . White ;
58
+ Console . Write ( "Assistant> " ) ;
59
+
60
+ // as each token (partial or whole word is streamed back) print it to the console, stream to web client, etc
47
61
await foreach (
48
62
var text
49
63
in session . ChatAsync (
@@ -56,71 +70,8 @@ in session.ChatAsync(
56
70
Console . WriteLine ( ) ;
57
71
58
72
Console . ForegroundColor = ConsoleColor . Green ;
73
+ Console . Write ( "User> " ) ;
59
74
userInput = Console . ReadLine ( ) ?? "" ;
60
-
61
- Console . ForegroundColor = ConsoleColor . White ;
62
- }
63
- }
64
-
65
- class LLama3HistoryTransform : IHistoryTransform
66
- {
67
- /// <summary>
68
- /// Convert a ChatHistory instance to plain text.
69
- /// </summary>
70
- /// <param name="history">The ChatHistory instance</param>
71
- /// <returns></returns>
72
- public string HistoryToText ( ChatHistory history )
73
- {
74
- string res = Bos ;
75
- foreach ( var message in history . Messages )
76
- {
77
- res += EncodeMessage ( message ) ;
78
- }
79
- res += EncodeHeader ( new ChatHistory . Message ( AuthorRole . Assistant , "" ) ) ;
80
- return res ;
81
- }
82
-
83
- private string EncodeHeader ( ChatHistory . Message message )
84
- {
85
- string res = StartHeaderId ;
86
- res += message . AuthorRole . ToString ( ) ;
87
- res += EndHeaderId ;
88
- res += "\n \n " ;
89
- return res ;
90
- }
91
-
92
- private string EncodeMessage ( ChatHistory . Message message )
93
- {
94
- string res = EncodeHeader ( message ) ;
95
- res += message . Content ;
96
- res += EndofTurn ;
97
- return res ;
98
75
}
99
-
100
- /// <summary>
101
- /// Converts plain text to a ChatHistory instance.
102
- /// </summary>
103
- /// <param name="role">The role for the author.</param>
104
- /// <param name="text">The chat history as plain text.</param>
105
- /// <returns>The updated history.</returns>
106
- public ChatHistory TextToHistory ( AuthorRole role , string text )
107
- {
108
- return new ChatHistory ( new ChatHistory . Message [ ] { new ChatHistory . Message ( role , text ) } ) ;
109
- }
110
-
111
- /// <summary>
112
- /// Copy the transform.
113
- /// </summary>
114
- /// <returns></returns>
115
- public IHistoryTransform Clone ( )
116
- {
117
- return new LLama3HistoryTransform ( ) ;
118
- }
119
-
120
- private const string StartHeaderId = "<|start_header_id|>" ;
121
- private const string EndHeaderId = "<|end_header_id|>" ;
122
- private const string Bos = "<|begin_of_text|>" ;
123
- private const string Eos = "<|end_of_text|>" ;
124
- private const string EndofTurn = "<|eot_id|>" ;
125
76
}
126
77
}
0 commit comments