Skip to content

Commit

Permalink
Adding support for Llama 3 and Phi3 (via Ollama) (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusschiesser authored Apr 24, 2024
1 parent 089916a commit f1c3e8d
Show file tree
Hide file tree
Showing 22 changed files with 662 additions and 372 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-beds-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-llama": minor
---

Add Llama3 and Phi3 support using Ollama
8 changes: 2 additions & 6 deletions create-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ export async function createApp({
appPath,
packageManager,
frontend,
openAiKey,
modelConfig,
llamaCloudKey,
model,
embeddingModel,
communityProjectConfig,
llamapack,
vectorDb,
Expand Down Expand Up @@ -77,10 +75,8 @@ export async function createApp({
ui,
packageManager,
isOnline,
openAiKey,
modelConfig,
llamaCloudKey,
model,
embeddingModel,
communityProjectConfig,
llamapack,
vectorDb,
Expand Down
183 changes: 90 additions & 93 deletions helpers/env-variables.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from "fs/promises";
import path from "path";
import {
ModelConfig,
TemplateDataSource,
TemplateFramework,
TemplateVectorDB,
Expand Down Expand Up @@ -28,7 +29,10 @@ const renderEnvVar = (envVars: EnvVar[]): string => {
);
};

const getVectorDBEnvs = (vectorDb: TemplateVectorDB) => {
const getVectorDBEnvs = (vectorDb?: TemplateVectorDB): EnvVar[] => {
if (!vectorDb) {
return [];
}
switch (vectorDb) {
case "mongo":
return [
Expand Down Expand Up @@ -130,84 +134,75 @@ const getVectorDBEnvs = (vectorDb: TemplateVectorDB) => {
}
};

export const createBackendEnvFile = async (
root: string,
opts: {
openAiKey?: string;
llamaCloudKey?: string;
vectorDb?: TemplateVectorDB;
model?: string;
embeddingModel?: string;
framework?: TemplateFramework;
dataSources?: TemplateDataSource[];
port?: number;
},
) => {
// Init env values
const envFileName = ".env";
const defaultEnvs = [
{
render: true,
name: "MODEL",
description: "The name of LLM model to use.",
value: opts.model,
},
const getModelEnvs = (modelConfig: ModelConfig): EnvVar[] => {
return [
{
render: true,
name: "OPENAI_API_KEY",
description: "The OpenAI API key to use.",
value: opts.openAiKey,
name: "MODEL_PROVIDER",
description: "The provider for the AI models to use.",
value: modelConfig.provider,
},
{
name: "LLAMA_CLOUD_API_KEY",
description: `The Llama Cloud API key.`,
value: opts.llamaCloudKey,
name: "MODEL",
description: "The name of LLM model to use.",
value: modelConfig.model,
},
{
name: "EMBEDDING_MODEL",
description: "Name of the embedding model to use.",
value: opts.embeddingModel,
value: modelConfig.embeddingModel,
},
{
name: "EMBEDDING_DIM",
description: "Dimension of the embedding model to use.",
value: 1536,
value: modelConfig.dimensions.toString(),
},
// Add vector database environment variables
...(opts.vectorDb ? getVectorDBEnvs(opts.vectorDb) : []),
...(modelConfig.provider === "openai"
? [
{
name: "OPENAI_API_KEY",
description: "The OpenAI API key to use.",
value: modelConfig.apiKey,
},
]
: []),
];
let envVars: EnvVar[] = [];
if (opts.framework === "fastapi") {
envVars = [
...defaultEnvs,
...[
{
name: "APP_HOST",
description: "The address to start the backend app.",
value: "0.0.0.0",
},
{
name: "APP_PORT",
description: "The port to start the backend app.",
value: opts.port?.toString() || "8000",
},
{
name: "LLM_TEMPERATURE",
description: "Temperature for sampling from the model.",
},
{
name: "LLM_MAX_TOKENS",
description: "Maximum number of tokens to generate.",
},
{
name: "TOP_K",
description:
"The number of similar embeddings to return when retrieving documents.",
value: "3",
},
{
name: "SYSTEM_PROMPT",
description: `Custom system prompt.
};

const getFrameworkEnvs = (
framework?: TemplateFramework,
port?: number,
): EnvVar[] => {
if (framework !== "fastapi") {
return [];
}
return [
{
name: "APP_HOST",
description: "The address to start the backend app.",
value: "0.0.0.0",
},
{
name: "APP_PORT",
description: "The port to start the backend app.",
value: port?.toString() || "8000",
},
{
name: "LLM_TEMPERATURE",
description: "Temperature for sampling from the model.",
},
{
name: "LLM_MAX_TOKENS",
description: "Maximum number of tokens to generate.",
},
{
name: "TOP_K",
description:
"The number of similar embeddings to return when retrieving documents.",
value: "3",
},
{
name: "SYSTEM_PROMPT",
description: `Custom system prompt.
Example:
SYSTEM_PROMPT="
We have provided context information below.
Expand All @@ -216,22 +211,35 @@ We have provided context information below.
---------------------
Given this information, please answer the question: {query_str}
"`,
},
],
];
} else {
const nextJsEnvs = [
{
name: "NEXT_PUBLIC_MODEL",
description: "The LLM model to use (hardcode to front-end artifact).",
value: opts.model,
},
];
envVars = [
...defaultEnvs,
...(opts.framework === "nextjs" ? nextJsEnvs : []),
];
}
},
];
};

export const createBackendEnvFile = async (
root: string,
opts: {
llamaCloudKey?: string;
vectorDb?: TemplateVectorDB;
modelConfig: ModelConfig;
framework?: TemplateFramework;
dataSources?: TemplateDataSource[];
port?: number;
},
) => {
// Init env values
const envFileName = ".env";
const envVars: EnvVar[] = [
{
name: "LLAMA_CLOUD_API_KEY",
description: `The Llama Cloud API key.`,
value: opts.llamaCloudKey,
},
// Add model environment variables
...getModelEnvs(opts.modelConfig),
// Add vector database environment variables
...getVectorDBEnvs(opts.vectorDb),
...getFrameworkEnvs(opts.framework, opts.port),
];
// Render and write env file
const content = renderEnvVar(envVars);
await fs.writeFile(path.join(root, envFileName), content);
Expand All @@ -242,20 +250,9 @@ export const createFrontendEnvFile = async (
root: string,
opts: {
customApiPath?: string;
model?: string;
},
) => {
const defaultFrontendEnvs = [
{
name: "MODEL",
description: "The OpenAI model to use.",
value: opts.model,
},
{
name: "NEXT_PUBLIC_MODEL",
description: "The OpenAI model to use (hardcode to front-end artifact).",
value: opts.model,
},
{
name: "NEXT_PUBLIC_CHAT_API",
description: "The backend API for chat endpoint.",
Expand Down
17 changes: 8 additions & 9 deletions helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { createBackendEnvFile, createFrontendEnvFile } from "./env-variables";
import { PackageManager } from "./get-pkg-manager";
import { installLlamapackProject } from "./llama-pack";
import { isHavingPoetryLockFile, tryPoetryRun } from "./poetry";
import { isModelConfigured } from "./providers";
import { installPythonTemplate } from "./python";
import { downloadAndExtractRepo } from "./repo";
import { ConfigFileType, writeToolsConfig } from "./tools";
import {
FileSourceConfig,
InstallTemplateArgs,
ModelConfig,
TemplateDataSource,
TemplateFramework,
TemplateVectorDB,
Expand All @@ -24,8 +26,8 @@ import { installTSTemplate } from "./typescript";
// eslint-disable-next-line max-params
async function generateContextData(
framework: TemplateFramework,
modelConfig: ModelConfig,
packageManager?: PackageManager,
openAiKey?: string,
vectorDb?: TemplateVectorDB,
llamaCloudKey?: string,
useLlamaParse?: boolean,
Expand All @@ -36,12 +38,12 @@ async function generateContextData(
? "poetry run generate"
: `${packageManager} run generate`,
)}`;
const openAiKeyConfigured = openAiKey || process.env["OPENAI_API_KEY"];
const modelConfigured = isModelConfigured(modelConfig);
const llamaCloudKeyConfigured = useLlamaParse
? llamaCloudKey || process.env["LLAMA_CLOUD_API_KEY"]
: true;
const hasVectorDb = vectorDb && vectorDb !== "none";
if (openAiKeyConfigured && llamaCloudKeyConfigured && !hasVectorDb) {
if (modelConfigured && llamaCloudKeyConfigured && !hasVectorDb) {
// If all the required environment variables are set, run the generate script
if (framework === "fastapi") {
if (isHavingPoetryLockFile()) {
Expand All @@ -63,7 +65,7 @@ async function generateContextData(

// generate the message of what to do to run the generate script manually
const settings = [];
if (!openAiKeyConfigured) settings.push("your OpenAI key");
if (!modelConfigured) settings.push("your model provider API key");
if (!llamaCloudKeyConfigured) settings.push("your Llama Cloud key");
if (hasVectorDb) settings.push("your Vector DB environment variables");
const settingsMessage =
Expand Down Expand Up @@ -141,11 +143,9 @@ export const installTemplate = async (

// Copy the environment file to the target directory.
await createBackendEnvFile(props.root, {
openAiKey: props.openAiKey,
modelConfig: props.modelConfig,
llamaCloudKey: props.llamaCloudKey,
vectorDb: props.vectorDb,
model: props.model,
embeddingModel: props.embeddingModel,
framework: props.framework,
dataSources: props.dataSources,
port: props.externalPort,
Expand All @@ -163,8 +163,8 @@ export const installTemplate = async (
) {
await generateContextData(
props.framework,
props.modelConfig,
props.packageManager,
props.openAiKey,
props.vectorDb,
props.llamaCloudKey,
props.useLlamaParse,
Expand All @@ -174,7 +174,6 @@ export const installTemplate = async (
} else {
// this is a frontend for a full-stack app, create .env file with model information
await createFrontendEnvFile(props.root, {
model: props.model,
customApiPath: props.customApiPath,
});
}
Expand Down
Loading

0 comments on commit f1c3e8d

Please sign in to comment.