Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a single model (granite3-dense) for chat and completion #139

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
`Paver` simplifies the setup of the
[Continue extension](https://marketplace.visualstudio.com/items?itemName=Continue.continue)
to integrate [IBM](https://www.ibm.com/)'s
[Granite code models](https://github.com/ibm-granite/granite-code-models), as
[Granite models](https://github.com/ibm-granite/granite-3.0-language-models), as
your code assistant in Visual Studio Code, using [Ollama](https://ollama.com/)
as the runtime environment.

By leveraging Granite code models and open-source components such as Ollama and
By leveraging Granite models and open-source components such as Ollama and
Continue, you can write, generate, explain, or document code with full control
over your data, ensuring it stays private and secure on your machine.

## Getting Started

This project features an intuitive UI, designed to simplify the installation and
management of Ollama and Granite Code models. The first time the extension
management of Ollama and Granite models. The first time the extension
starts, a setup wizard is automatically launched to guide you through the
installation process.

You can later open the setup wizard anytime from the command palette by
executing the _"Paver: Setup Granite Code as code assistant"_ command.
executing the _"Paver: Setup Granite as code assistant"_ command.

### Installation Prerequisites

Expand Down Expand Up @@ -72,20 +72,20 @@ interact with the models via the UI or tab completion.

## About the Stack

### IBM Granite Code Models
### IBM Granite Models

The Granite Code models are optimized for enterprise software development
The Granite models are optimized for enterprise software development
workflows, performing well across various coding tasks (e.g., code generation,
fixing, and explanation). They are versatile "all-around" code models.

Granite Code comes in various sizes to fit your workstation's resources.
Granite comes in various sizes to fit your workstation's resources.
Generally, larger models yield better results but require more disk space,
memory, and processing power.

**Recommendation:** Use Model Size 8B for chat and 8B for tab code completion.
**Recommendation:** Using Model Size 2B should work on most machines. Use the 8b version if you're running on a high-end computer.

For more details, refer to
[Granite Code Models](https://github.com/ibm-granite/granite-code-models).
[Granite Models](https://github.com/ibm-granite/granite-3.0-language-models).

### Ollama

Expand Down
Binary file modified media/installmodels.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified media/installollama.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
{
"command": "paver.setup",
"category": "Paver",
"title": "Setup Granite Code as code assistant"
"title": "Setup Granite as code assistant"
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion src/commons/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const EXTENSION_ID = 'redhat.vscode-paver';
export const isDevMode = process.env.PAVER_EXT_DEV_MODE === 'true';
export const DOWNLOADABLE_MODELS = ['nomic-embed-text:latest', 'granite-code:3b', 'granite-code:8b', 'granite-code:20b', 'granite-code:34b'];
export const DOWNLOADABLE_MODELS = ['nomic-embed-text:latest', 'granite-code:3b', 'granite-code:8b', 'granite3-dense:2b', 'granite3-dense:8b'];

16 changes: 8 additions & 8 deletions src/commons/modelInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ export const DEFAULT_MODEL_INFO = new Map<string, ModelInfo>();
digest: ''
},
{
id: 'granite-code:3b',
size: '274MB',
id: 'granite3-dense:2b',
size: '1.6GB',
digest: ''
},
{
id: 'granite-code:8b',
size: '4GB',
id: 'granite3-dense:8b',
size: '4.9GB',
digest: ''
},
{
id: 'granite-code:20b',
size: '12GB',
id: 'granite-code:3b',
size: '2GB',
digest: ''
},
{
id: 'granite-code:34b',
size: '20GB',
id: 'granite-code:8b',
size: '4GB',
digest: ''
}
].forEach((m: ModelInfo) => {
Expand Down
14 changes: 7 additions & 7 deletions src/configureAssistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export interface AiAssistantConfigurationRequest {
embeddingsModel: string | null;
}

const DEFAULT_CONTEXT_LENGTH = 8192;
const DEFAULT_CONTEXT_LENGTH = 4096;
const DEFAULT_API_BASE = "http://localhost:11434";
const DEFAULT_PROVIDER = "ollama";

Expand All @@ -48,33 +48,33 @@ const baseGraniteConfig: Partial<ModelConfig> = {
...baseConfig,
contextLength: DEFAULT_CONTEXT_LENGTH,
completionOptions: {
maxTokens: 4000,
temperature: 0.1,
maxTokens: DEFAULT_CONTEXT_LENGTH / 2,
temperature: 0,
topP: 0.9,
topK: 40,
presencePenalty: 0.0,
frequencyPenalty: 0.1
},
systemMessage: "You are Granite Code, an AI language model developed by IBM. You are a cautious assistant. You carefully follow instructions. You are helpful and harmless and you follow ethical guidelines and promote positive behavior. You always respond to greetings (for example, hi, hello, g'day, morning, afternoon, evening, night, what's up, nice to meet you, sup, etc) with \"Hello! I am Granite Code, created by IBM. How can I help you today?\". Please do not say anything else and do not start a conversation.",
systemMessage: "You are Granite Code, an AI language model developed by IBM. You are a cautious assistant. You carefully follow instructions. You are helpful and harmless and you follow ethical guidelines and promote positive behavior.",
};

const modelConfigs: ModelConfig[] = [
{
model: "granite-code:3b",
...baseGraniteConfig,
contextLength: 128000,
contextLength: 24000,
},
{
model: "granite-code:8b",
...baseGraniteConfig,
contextLength: 128000,
},
{
model: "granite-code:20b",
model: "granite3-dense:2b",
...baseGraniteConfig,
},
{
model: "granite-code:34b",
model: "granite3-dense:8b",
...baseGraniteConfig,
},
{
Expand Down
1 change: 0 additions & 1 deletion src/ollama/ollamaLibrary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export async function getRemoteModelInfo(modelId: string): Promise<ModelInfo | u
if (!response.ok) {
throw new Error(`Failed to fetch the model page: ${response.statusText}`);
}

const html = await response.text();
const root = parse(html);
const fileExplorer = root.querySelector('#file-explorer');
Expand Down
3 changes: 2 additions & 1 deletion src/panels/setupGranitePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ export class SetupGranitePage {

console.log("Starting Granite Code AI-Assistant configuration...");
const chatModel = graniteConfiguration.chatModelId;
const tabModel = graniteConfiguration.tabModelId;

const tabModel = graniteConfiguration.chatModelId; //TODO enable when advanced setup is available graniteConfiguration.tabModelId;
const embeddingsModel = graniteConfiguration.embeddingsModelId;
// Collect all unique models to install from graniteConfiguration
const modelsToInstall: string[] = []; //I'd prefer using a sorted set but there's no such thing in vanilla typescript
Expand Down
18 changes: 9 additions & 9 deletions webviews/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('App Component', () => {
beforeEach(() => {
// Clear mocks before each test
jest.clearAllMocks();

// Setup message event listener
window.addEventListener = jest.fn((event: string, handler: EventListenerOrEventListenerObject) => {
if (event === 'message') {
Expand All @@ -34,7 +34,7 @@ describe('App Component', () => {

it('renders the main title', () => {
render(<App />);
const titleElement = screen.getByText(/Setup IBM Granite Code as your code assistant with Continue/i);
const titleElement = screen.getByText(/Setup IBM Granite as your code assistant with Continue/i);
expect(titleElement).toBeInTheDocument();
});

Expand Down Expand Up @@ -66,7 +66,7 @@ describe('App Component', () => {
});

// Click the button
const setupButton = screen.getByText('Setup Granite Code');
const setupButton = screen.getByText('Setup Granite');
await act(async () => {
fireEvent.click(setupButton);
// Wait for state updates
Expand All @@ -77,8 +77,8 @@ describe('App Component', () => {
expect(mockPostMessage).toHaveBeenCalledWith({
command: 'setupGranite',
data: {
tabModelId: 'granite-code:8b',
chatModelId: 'granite-code:8b',
chatModelId: 'granite3-dense:2b',
tabModelId: null,
embeddingsModelId: 'nomic-embed-text:latest'
}
});
Expand All @@ -105,7 +105,7 @@ describe('App Component', () => {
} as MessageEvent);
});

const setupButton = screen.getByText('Setup Granite Code');
const setupButton = screen.getByText('Setup Granite');
expect(setupButton).toBeDisabled();
});

Expand Down Expand Up @@ -146,7 +146,7 @@ describe('App Component', () => {
});

// Click the setup button
const setupButton = screen.getByText('Setup Granite Code');
const setupButton = screen.getByText('Setup Granite');
await act(async () => {
fireEvent.click(setupButton);
await new Promise(resolve => setTimeout(resolve, 0));
Expand All @@ -156,8 +156,8 @@ describe('App Component', () => {
expect(mockPostMessage).toHaveBeenCalledWith({
command: 'setupGranite',
data: {
tabModelId: 'granite-code:8b',
chatModelId: 'granite-code:8b',
chatModelId: 'granite3-dense:2b',
tabModelId: null,
embeddingsModelId: 'nomic-embed-text:latest'
}
});
Expand Down
23 changes: 14 additions & 9 deletions webviews/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import { StatusCheck, StatusValue } from "./StatusCheck";

function App() {
const modelOptions: ModelOption[] = [
{ label: 'granite3-dense:2b', value: 'granite3-dense:2b', info: '1.6 GB' },
{ label: 'granite3-dense:8b', value: 'granite3-dense:8b', info: '4.9 GB' },
{ label: 'granite-code:3b', value: 'granite-code:3b', info: '2.0 GB' },
{ label: 'granite-code:8b', value: 'granite-code:8b', info: '4.6 GB' },
{ label: 'granite-code:20b', value: 'granite-code:20b', info: '12 GB' },
{ label: 'granite-code:34b', value: 'granite-code:34b', info: '19 GB' },
{ label: 'Keep existing configuration', value: null, info: null }
];

const tabOptions: ModelOption[] = [
{ label: 'granite3-dense:2b', value: 'granite3-dense:2b', info: '1.6 GB' },
{ label: 'granite3-dense:8b', value: 'granite3-dense:8b', info: '4.9 GB' },
{ label: 'granite-code:3b', value: 'granite-code:3b', info: '2.0 GB' },
{ label: 'granite-code:8b', value: 'granite-code:8b', info: '4.6 GB' },
{ label: 'Keep existing configuration', value: null, info: null }
Expand All @@ -27,8 +29,8 @@ function App() {
{ label: 'Keep existing configuration', value: null, info: null }
];

const [tabModel, setTabModel] = useState<string | null>(tabOptions[1].value); //use 8b by default
const [chatModel, setChatModel] = useState<string | null>(modelOptions[1].value);//use 8b by default
const [tabModel, setTabModel] = useState<string | null>(null); //tabOptions[3].value use 3b by default
const [chatModel, setChatModel] = useState<string | null>(modelOptions[0].value);//use dense:2b by default
const [embeddingsModel, setEmbeddingsModel] = useState<string | null>(embeddingsOptions[0].value);

const [modelPullProgress, setModelPullProgress] = useState<{
Expand Down Expand Up @@ -193,11 +195,11 @@ function App() {

return (
<main className="main-wrapper">
<h1 className="main-title">Setup IBM Granite Code as your code assistant with Continue</h1>
<h1 className="main-title">Setup IBM Granite as your code assistant with Continue</h1>

<div className="main-description">
<p className="m-0 mb-1">
Run <a href="https://github.com/ibm-granite/granite-code-models" target="_blank" rel="noopener noreferrer">IBM Granite Code</a> models effortlessly with
Run <a href="https://github.com/ibm-granite/granite-3.0-language-models" target="_blank" rel="noopener noreferrer">IBM Granite</a> models effortlessly with
<a href="https://github.com/ollama/ollama" target="_blank" rel="noopener noreferrer"> Ollama</a> and <a href="https://github.com/continuedev/continue" target="_blank" rel="noopener noreferrer">Continue</a>.
Granite will help you write, generate, explain or document code, while your data stays secure and private on your own machine.
</p>
Expand Down Expand Up @@ -235,15 +237,17 @@ function App() {

<ModelList
className="model-list"
label="Chat model"
label="Granite model"
value={chatModel}
onChange={(e) => setChatModel(e?.value ?? null)}
status={getModelStatus(chatModel)}
options={modelOptions}
progress={chatModel ? modelPullProgress[chatModel] : undefined}
disabled={!enabled}
tooltip="This model will be used for Chat and Tab Completion"
/>

{/*
<ModelList
className="model-list"
label="Tab completion model"
Expand All @@ -254,6 +258,7 @@ function App() {
progress={tabModel ? modelPullProgress[tabModel] : undefined}
disabled={!enabled}
/>
*/}

<ModelList
className="model-list"
Expand All @@ -268,15 +273,15 @@ function App() {

<div className="final-setup-group">
<button className="install-button" onClick={handleSetupGraniteClick} disabled={serverStatus !== ServerStatus.started || !enabled || isKeepExistingConfigSelected}>
Setup Granite Code
Setup Granite
</button>
</div>
</div>

<div className="info-message">
<p>
To reopen this wizard, open the command palette and run:
<p style={{ margin: 2, paddingLeft: 10 }}><strong>Paver: Setup Granite Code as code assistant</strong></p>.
<p style={{ margin: 2, paddingLeft: 10 }}><strong>Paver: Setup Granite as code assistant</strong></p>.
</p>
</div>
</main>
Expand Down
5 changes: 3 additions & 2 deletions webviews/src/ModelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ interface ModelListProps {
status: ModelStatus | null;
options: ModelOption[];
progress?: ProgressData;
tooltip?: string;
disabled?: boolean;
}

const ModelList: React.FC<ModelListProps> = ({ className, label, value, onChange, status, options, progress, disabled }) => {
const ModelList: React.FC<ModelListProps> = ({ className, label, value, onChange, status, options, progress, tooltip, disabled }) => {
const selectHeight = '16px';
const customStyles = {
container: (base: any) => ({
Expand Down Expand Up @@ -123,7 +124,7 @@ const ModelList: React.FC<ModelListProps> = ({ className, label, value, onChange

<label className='model-list--label' htmlFor={label}>
<StatusCheck type={getIconType(status)} title={getTitle(status)} />
<span>{label}:</span>
<span title={tooltip}>{label}:</span>
</label>

<div className={className + `--wrapper`}>
Expand Down