Skip to content

Commit

Permalink
fix: Fixed Together issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
HavenDV committed Mar 6, 2024
1 parent 629d9a4 commit 91acd6c
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 156 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,25 +60,26 @@ var answer = await llm.GenerateAsync(
""", cancellationToken: CancellationToken.None).ConfigureAwait(false);

Console.WriteLine($"LLM answer: {answer}"); // The cloaked figure.
Console.WriteLine($"LLM usage: {llm.Usage}");
Console.WriteLine($"Embeddings usage: {embeddings.Usage}");
// 2. Chains
var promptText =
var promptTemplate =
@"Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. Always quote the context in your answer.
{context}
Question: {text}
Helpful Answer:";

var chain =
Set("Who was drinking a unicorn blood?") // set the question
| RetrieveDocuments(index, amount: 5) // take 5 most similar documents
| StuffDocuments(outputKey: "context") // combine documents together and put them into context
| Template(promptText) // replace context and question in the prompt with their values
| LLM(llm.UseConsoleForDebug()); // send the result to the language model
var chainAnswer = await chain.Run("text"); // get chain result
Console.WriteLine("Answer:"+ chainAnswer); // print the result
Set("Who was drinking a unicorn blood?") // set the question (default key is "text")
| RetrieveSimilarDocuments(index, amount: 5) // take 5 most similar documents
| CombineDocuments(outputKey: "context") // combine documents together and put them into context
| Template(promptTemplate) // replace context and question in the prompt with their values
| LLM(llm.UseConsoleForDebug()); // send the result to the language model
var chainAnswer = await chain.Run("text"); // get chain result
Console.WriteLine("Chain Answer:"+ chainAnswer); // print the result
Console.WriteLine($"LLM usage: {llm.Usage}"); // Print usage and price
Console.WriteLine($"Embeddings usage: {embeddings.Usage}"); // Print usage and price
```

## Contributors
Expand Down
89 changes: 48 additions & 41 deletions src/Meta/test/OpenAiTests.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
// using FluentAssertions;
// using LangChain.Base;
// using LangChain.Callback;
// using LangChain.Chains.LLM;
// using LangChain.LLMS.OpenAi;
// using LangChain.Prompts;
// using LangChain.Schema;
//
// namespace LangChain.IntegrationTests;
//
// public class OpenAiTests
// {
// [Fact]
// public async Task TestOpenAi_WithValidInput_ShouldReturnResponse()
// {
// var model = new OpenAi();
//
// var result = await model.Call("What is a good name for a company that sells colourful socks?");
//
// result.Should().NotBeEmpty();
// }
//
// [Fact]
// public async Task TestOpenAi_WithChain_ShouldReturnResponse()
// {
// var llm = new OpenAi();
//
// var template = "What is a good name for a company that makes {product}?";
// var prompt = new PromptTemplate(new PromptTemplateInput(template, new List<string>(1){"product"}));
//
// var chain = new LlmChain(new LlmChainInput(llm, prompt));
//
// var result = await chain.Call(new ChainValues(new Dictionary<string, object>(1)
// {
// { "product", "colourful socks" }
// }));
//
// // The result is an object with a `text` property.
// result.Value["text"].ToString().Should().NotBeEmpty();
// }
// }
using LangChain.Chains.LLM;
using LangChain.Prompts;
using LangChain.Providers.OpenAI.Predefined;
using LangChain.Schema;

namespace LangChain.IntegrationTests;

[TestFixture]
[Explicit]
public class OpenAiTests
{
[Test]
public async Task TestOpenAi_WithValidInput_ShouldReturnResponse()
{
var model = new Gpt35TurboModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));

string result = await model.GenerateAsync("What is a good name for a company that sells colourful socks?");

result.Should().NotBeEmpty();

Console.WriteLine(result);
}

[Test]
public async Task TestOpenAi_WithChain_ShouldReturnResponse()
{
var llm = new Gpt35TurboModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));

var template = "What is a good name for a company that makes {product}?";
var prompt = new PromptTemplate(new PromptTemplateInput(template, new List<string>(1){"product"}));

var chain = new LlmChain(new LlmChainInput(llm, prompt));

var result = await chain.CallAsync(new ChainValues(new Dictionary<string, object>(1)
{
{ "product", "colourful socks" }
}));

// The result is an object with a `text` property.
result.Value["text"].ToString().Should().NotBeEmpty();

Console.WriteLine(result.Value["text"]);
}
}
166 changes: 74 additions & 92 deletions src/Meta/test/ReadmeTests.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
using LangChain.Databases;
using LangChain.Databases.InMemory;
using LangChain.Sources;
using LangChain.Indexes;
using LangChain.Providers;
using LangChain.Providers.Anyscale;
using LangChain.Providers.Anyscale.Predefined;
using LangChain.Providers.OpenAI;
using LangChain.Providers.OpenAI.Predefined;
using LangChain.Splitters.Text;
using LangChain.VectorStores;
using static LangChain.Chains.Chain;

namespace LangChain.IntegrationTests;

[TestFixture]
[Explicit]
public class ReadmeTests
{
[Explicit]
[Test]
public async Task Chains1()
{
Expand Down Expand Up @@ -61,71 +61,11 @@ Human will provide you with sentence about pet. You need to answer with pet name
result.Should().Be("Bob");
}

/// <summary>
/// Price to run from zero(create embedding and request to LLM): 0,015$
/// Price to re-run if database is exists: 0,0004$
/// </summary>
/// <exception cref="InconclusiveException"></exception>
[Explicit]
[Test]
public async Task RagWithOpenAiUsingChains()
{
var gpt35 = new Gpt35TurboModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));
var embeddings = new TextEmbeddingV3SmallModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));

// Create database with embeddings from Harry Potter book pdf
if (!File.Exists("vectors.db"))
{
await using var stream = H.Resources.HarryPotterBook1_pdf.AsStream();
var documents = await PdfPigPdfSource.FromStreamAsync(stream);

await SQLiteVectorStore.CreateIndexFromDocuments(
embeddings: embeddings,
documents: documents,
filename: "vectors.db",
tableName: "vectors",
textSplitter: new RecursiveCharacterTextSplitter(
chunkSize: 200,
chunkOverlap: 50));
}

var vectorStore = new SQLiteVectorStore("vectors.db", "vectors", embeddings);
var index = new VectorStoreIndexWrapper(vectorStore);
var chain =
// set the question
Set("Who was drinking a unicorn blood?", outputKey: "question") |
// take 5 most similar documents
RetrieveSimilarDocuments(index, inputKey: "question", outputKey: "documents", amount: 5) |
// combine documents together and put them into context
CombineDocuments(inputKey: "documents", outputKey: "context") |
// replace context and question in the prompt with their values
Template(@"Use the following pieces of context to answer the question at the end.
If the answer is not in context then just say that you don't know, don't try to make up an answer.
Keep the answer as short as possible.
{context}
Question: {question}
Helpful Answer:") |
// send the result to the language model
LargeLanguageModel(gpt35);

var result = await chain.Run("text");

Console.WriteLine($"LLM answer: {result}");
Console.WriteLine($"Total usage: {gpt35.Usage}");
}

/// <summary>
/// Price to run from zero(create embeddings and request to LLM): 0,015$
/// Price to re-run if database is exists: 0,0004$
/// </summary>
/// <exception cref="InconclusiveException"></exception>
[Explicit]
[Test]
public async Task Readme()
{
Expand Down Expand Up @@ -161,46 +101,86 @@ Keep the answer as short as possible.
""", cancellationToken: CancellationToken.None).ConfigureAwait(false);

Console.WriteLine($"LLM answer: {answer}"); // The cloaked figure.
Console.WriteLine($"LLM usage: {llm.Usage}");
Console.WriteLine($"Embeddings usage: {embeddings.Usage}");

// 2. Chains
var promptText =
var promptTemplate =
@"Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. Always quote the context in your answer.
{context}
Question: {text}
Helpful Answer:";

var chain =
Set("Who was drinking a unicorn blood?") // set the question
| RetrieveDocuments(index, amount: 5) // take 5 most similar documents
| StuffDocuments(outputKey: "context") // combine documents together and put them into context
| Template(promptText) // replace context and question in the prompt with their values
| LLM(llm.UseConsoleForDebug()); // send the result to the language model
var chainAnswer = await chain.Run("text"); // get chain result
Set("Who was drinking a unicorn blood?") // set the question (default key is "text")
| RetrieveSimilarDocuments(index, amount: 5) // take 5 most similar documents
| CombineDocuments(outputKey: "context") // combine documents together and put them into context
| Template(promptTemplate) // replace context and question in the prompt with their values
| LLM(llm.UseConsoleForDebug()); // send the result to the language model
var chainAnswer = await chain.Run("text"); // get chain result

Console.WriteLine("Chain Answer:"+ chainAnswer); // print the result

Console.WriteLine("Answer:"+ chainAnswer); // print the result
Console.WriteLine($"LLM usage: {llm.Usage}"); // Print usage and price
Console.WriteLine($"Embeddings usage: {embeddings.Usage}"); // Print usage and price
}

[Explicit]
private enum ProviderType
{
OpenAi,
Together,
Anyscale,
}

private (IChatModel ChatModel, IEmbeddingModel EmbeddingModel) GetModels(ProviderType providerType)
{
switch (providerType)
{
case ProviderType.OpenAi:
{
var provider = new OpenAiProvider(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));
var llm = new Gpt35TurboModel(provider);
var embeddings = new TextEmbeddingV3SmallModel(provider);

return (llm, embeddings);
}
case ProviderType.Together:
{
// https://www.together.ai/blog/embeddings-endpoint-release
var provider = new OpenAiProvider(
apiKey: Environment.GetEnvironmentVariable("TOGETHER_API_KEY") ??
throw new InconclusiveException("TOGETHER_API_KEY is not set"),
customEndpoint: "api.together.xyz");
var llm = new OpenAiChatModel(provider, id: "meta-llama/Llama-2-70b-chat-hf");
var embeddings = new OpenAiEmbeddingModel(provider, id: "togethercomputer/m2-bert-80M-2k-retrieval");

return (llm, embeddings);
}
case ProviderType.Anyscale:
{
// https://app.endpoints.anyscale.com/
var provider = new AnyscaleProvider(
apiKey: Environment.GetEnvironmentVariable("ANYSCALE_API_KEY") ??
throw new InconclusiveException("ANYSCALE_API_KEY is not set"));
var llm = new Llama2LargeModel(provider);

// Use OpenAI embeddings for now because Anyscale doesn't have embeddings yet
var embeddings = new TextEmbeddingV3SmallModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));

return (llm, embeddings);
}

default:
throw new ArgumentOutOfRangeException();
}
}

[Test]
public async Task SimpleDocuments()
public async Task SimpleTestUsingAsync()
{
// https://www.together.ai/blog/embeddings-endpoint-release
// var together = new OpenAiModel(new OpenAiConfiguration
// {
// ApiKey = Environment.GetEnvironmentVariable("TOGETHER_API_KEY") ??
// throw new InconclusiveException("TOGETHER_API_KEY is not set"),
// Endpoint = "api.together.xyz",
// ModelId = "togethercomputer/Qwen-7B",
// EmbeddingModelId = "togethercomputer/m2-bert-80M-32k-retrieval",
// });
var gpt35 = new Gpt35TurboModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));
var embeddings = new TextEmbeddingV3SmallModel(
Environment.GetEnvironmentVariable("OPENAI_API_KEY") ??
throw new InconclusiveException("OPENAI_API_KEY is not set"));
var (llm, embeddings) = GetModels(ProviderType.OpenAi);

var database = await InMemoryVectorStore.CreateIndexFromDocuments(embeddings, new[]
{
Expand All @@ -213,7 +193,9 @@ public async Task SimpleDocuments()
const string question = "What is the good name for a pet?";
var similarDocuments = await database.Store.GetSimilarDocuments(question, amount: 1);

var petNameResponse = await gpt35.GenerateAsync(
Console.WriteLine($"Similar Documents: {similarDocuments.AsString()}");

var petNameResponse = await llm.GenerateAsync(
$"""
Human will provide you with sentence about pet. You need to answer with pet name.
Expand All @@ -227,7 +209,7 @@ Human will provide you with sentence about pet. You need to answer with pet name
""", cancellationToken: CancellationToken.None).ConfigureAwait(false);

Console.WriteLine($"LLM answer: {petNameResponse}");
Console.WriteLine($"Total usage: {gpt35.Usage}");
Console.WriteLine($"Total usage: {llm.Usage}");

petNameResponse.ToString().Should().Be("Bob");
}
Expand Down
10 changes: 2 additions & 8 deletions src/Providers/Abstractions/src/Chat/ChatRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ public static implicit operator ChatRequest(Message[] messages)
/// <returns></returns>
public static ChatRequest ToChatRequest(string message)
{
return new ChatRequest
{
Messages = new[] { message.AsSystemMessage() },
};
return ToChatRequest(message.AsHumanMessage());
}

/// <summary>
Expand All @@ -57,10 +54,7 @@ public static ChatRequest ToChatRequest(string message)
/// <returns></returns>
public static ChatRequest ToChatRequest(Message message)
{
return new ChatRequest
{
Messages = [message],
};
return ToChatRequest([message]);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Providers/Anyscale/src/AnyscaleProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public AnyscaleProvider(AnyscaleConfiguration configuration) : base(configuratio
{
}

public AnyscaleProvider(string apiKey) : base(apiKey, customEndpoint: "https://api.endpoints.anyscale.com/v1")
public AnyscaleProvider(string apiKey) : base(apiKey, customEndpoint: "api.endpoints.anyscale.com")
{
}
}
Loading

0 comments on commit 91acd6c

Please sign in to comment.