Skip to content

Commit c640deb

Browse files
donghyeon639tae0y
andauthored
Connector Implementation & Inheritance Ollama (#456)
* Connector Implementation & Inheritance * Update OllamaConnectorTests.cs with latest improvements * fix OllamaconnetcorTests.cs * fix: ollama bicep, ollama.md * fix resuorces.bicep, mainparemeter.json * ollama test fix * fix ollama.md Ollamatests * fix ollama test * fix ollama bicep * fix root README.md * fix ollamatest , ollama.md * fix ollamatest, ollama.md * ollama test languagemodel unit test * Update ollama.md - 기본모델 이외에 추가모델을 3개에서 1개로 변경함 - 레포 루트경로 확인하는 단계 위치를 수정함 - Azure Serverless GPU 사용하는 단계 추가함 * Update OllamaConnectorTests.cs - 테스트 주입 데이터를 InlineData로 이동 - 테스트명에 테스트하는 메서드명을 기재 - CreateChatClientAsync에서 settings가 null인 경우 테스트 추가 * Update OllamaConnectorTests.cs - expected 예외타입 수정 --------- Co-authored-by: tae0y[박태영] <[email protected]>
1 parent 1257cff commit c640deb

File tree

9 files changed

+607
-3
lines changed

9 files changed

+607
-3
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Open Chat Playground (OCP) is a web UI that is able to connect virtually any LLM
1313
- [x] [Docker Model Runner](https://docs.docker.com/ai/model-runner)
1414
- [x] [Foundry Local](https://learn.microsoft.com/azure/ai-foundry/foundry-local/what-is-foundry-local)
1515
- [x] [Hugging Face](https://huggingface.co/docs)
16-
- [ ] [Ollama](https://github.com/ollama/ollama/tree/main/docs)
16+
- [x] [Ollama](https://github.com/ollama/ollama/tree/main/docs)
1717
- [ ] [Anthropic](https://docs.anthropic.com)
1818
- [ ] [Naver](https://api.ncloud-docs.com/docs/ai-naver-clovastudio-summary)
1919
- [x] [LG](https://github.com/LG-AI-EXAONE)
@@ -66,6 +66,7 @@ Open Chat Playground (OCP) is a web UI that is able to connect virtually any LLM
6666
- [Use Docker Model Runner](./docs/docker-model-runner.md#run-on-local-machine)
6767
- [Use Foundry Local](./docs/foundry-local.md#run-on-local-machine)
6868
- [Use Hugging Face](./docs/hugging-face.md#run-on-local-machine)
69+
- [Use Ollama](./docs/ollama.md#run-on-local-machine)
6970
- [Use LG](./docs/lg.md#run-on-local-machine)
7071
- [Use OpenAI](./docs/openai.md#run-on-local-machine)
7172
- [Use Upstage](./docs/upstage.md#run-on-local-machine)
@@ -78,6 +79,7 @@ Open Chat Playground (OCP) is a web UI that is able to connect virtually any LLM
7879
- [Use Docker Model Runner](./docs/docker-model-runner.md#run-in-local-container)
7980
- ~~Use Foundry Local~~ 👉 NOT SUPPORTED
8081
- [Use Hugging Face](./docs/hugging-face.md#run-in-local-container)
82+
- [Use Ollama](./docs/ollama.md#run-on-local-container)
8183
- [Use LG](./docs/lg.md#run-in-local-container)
8284
- [Use OpenAI](./docs/openai.md#run-in-local-container)
8385
- [Use Upstage](./docs/upstage.md#run-in-local-container)
@@ -90,6 +92,7 @@ Open Chat Playground (OCP) is a web UI that is able to connect virtually any LLM
9092
- ~~Use Docker Model Runner~~ 👉 NOT SUPPORTED
9193
- ~~Use Foundry Local~~ 👉 NOT SUPPORTED
9294
- [Use Hugging Face](./docs/hugging-face.md#run-on-azure)
95+
- [Use Ollama](./docs/ollama.md#run-on-azure)
9396
- [Use LG](./docs/lg.md#run-on-azure)
9497
- [Use OpenAI](./docs/openai.md#run-on-azure)
9598
- [Use Upstage](./docs/upstage.md#run-on-azure)

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Docker Model Runner](./docker-model-runner.md)
77
- [Foundry Local](./foundry-local.md)
88
- [Hugging Face](./hugging-face.md)
9+
- [Ollama](ollama.md)
910
- [LG](./lg.md)
1011
- [OpenAI](./openai.md)
1112
- [Upstage](./upstage.md)

docs/ollama.md

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# OpenChat Playground with Ollama
2+
3+
This page describes how to run OpenChat Playground (OCP) with [Ollama](https://ollama.com/search) integration.
4+
5+
## Get the repository root
6+
7+
1. Get the repository root.
8+
9+
```bash
10+
# bash/zsh
11+
REPOSITORY_ROOT=$(git rev-parse --show-toplevel)
12+
```
13+
14+
```powershell
15+
# PowerShell
16+
$REPOSITORY_ROOT = git rev-parse --show-toplevel
17+
```
18+
19+
## Run on local machine
20+
21+
1. Make sure Ollama is installed and running on your local machine. If not, install Ollama from [ollama.com](https://ollama.com/) and start the service.
22+
23+
```bash
24+
ollama serve
25+
```
26+
27+
1. Pull the model you want to use. The default model OCP uses is "llama3.2"
28+
29+
```bash
30+
ollama pull llama3.2
31+
```
32+
33+
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, download it first by running the following command.
34+
35+
```bash
36+
ollama pull qwen
37+
```
38+
39+
2. Make sure you are at the repository root.
40+
41+
```bash
42+
cd $REPOSITORY_ROOT
43+
```
44+
45+
3. Run the app.
46+
47+
```bash
48+
# bash/zsh
49+
dotnet run --project $REPOSITORY_ROOT/src/OpenChat.PlaygroundApp -- \
50+
--connector-type Ollama
51+
```
52+
53+
```powershell
54+
# PowerShell
55+
dotnet run --project $REPOSITORY_ROOT\src\OpenChat.PlaygroundApp -- `
56+
--connector-type Ollama
57+
```
58+
59+
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, download it first by running the following command.
60+
61+
```bash
62+
# bash/zsh
63+
dotnet run --project $REPOSITORY_ROOT/src/OpenChat.PlaygroundApp -- \
64+
--connector-type Ollama \
65+
--model qwen
66+
```
67+
68+
```powershell
69+
# PowerShell
70+
dotnet run --project $REPOSITORY_ROOT\src\OpenChat.PlaygroundApp -- `
71+
--connector-type Ollama `
72+
--model qwen
73+
```
74+
75+
4. Open your web browser, navigate to `http://localhost:5280`, and enter prompts.
76+
77+
## Run on local container
78+
79+
This approach runs OpenChat Playground in a container while connecting to Ollama running on the host machine.
80+
81+
1. Configure Ollama to accept connections from containers.
82+
83+
```bash
84+
ollama serve
85+
```
86+
87+
1. Pull the model you want to use, and verify Ollama is accessible
88+
89+
```bash
90+
ollama pull llama3.2
91+
curl http://localhost:11434/api/version
92+
```
93+
94+
```powershell
95+
ollama pull llama3.2
96+
Invoke-RestMethod -Uri http://localhost:11434/api/version
97+
```
98+
99+
1. Make sure you are at the repository root.
100+
101+
```bash
102+
cd $REPOSITORY_ROOT
103+
```
104+
105+
1. Build a container.
106+
107+
```bash
108+
docker build -f Dockerfile -t openchat-playground:latest .
109+
```
110+
111+
1. Run the app.
112+
113+
```bash
114+
# bash/zsh - from locally built container
115+
docker run -i --rm -p 8080:8080 openchat-playground:latest \
116+
--connector-type Ollama \
117+
--base-url http://host.docker.internal:11434 \
118+
```
119+
120+
```powershell
121+
# PowerShell - from locally built container
122+
docker run -i --rm -p 8080:8080 openchat-playground:latest `
123+
--connector-type Ollama `
124+
--base-url http://host.docker.internal:11434
125+
```
126+
127+
```bash
128+
# bash/zsh - from GitHub Container Registry
129+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest\
130+
--connector-type Ollama \
131+
--base-url http://host.docker.internal:11434
132+
```
133+
134+
```powershell
135+
# PowerShell - from GitHub Container Registry
136+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest `
137+
--connector-type Ollama `
138+
--base-url http://host.docker.internal:11434
139+
```
140+
141+
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen), make sure you've already downloaded the model by running the `ollama pull qwen` command.
142+
143+
```bash
144+
ollama pull qwen
145+
```
146+
147+
```bash
148+
# bash/zsh - from locally built container
149+
docker run -i --rm -p 8080:8080 openchat-playground:latest \
150+
--connector-type Ollama \
151+
--base-url http://host.docker.internal:11434 \
152+
--model qwen
153+
```
154+
155+
```powershell
156+
# PowerShell - from locally built container
157+
docker run -i --rm -p 8080:8080 openchat-playground:latest `
158+
--connector-type Ollama `
159+
--base-url http://host.docker.internal:11434 `
160+
--model qwen
161+
```
162+
163+
```bash
164+
# bash/zsh - from GitHub Container Registry
165+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest\
166+
--connector-type Ollama \
167+
--base-url http://host.docker.internal:11434 \
168+
--model qwen
169+
```
170+
171+
```powershell
172+
# PowerShell - from GitHub Container Registry
173+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest `
174+
--connector-type Ollama `
175+
--base-url http://host.docker.internal:11434 `
176+
--model qwen
177+
```
178+
179+
> **NOTE**: Use `host.docker.internal:11434` to connect to Ollama running on the host machine from inside the container.
180+
181+
1. Open your web browser, navigate to `http://localhost:8080`, and enter prompts.
182+
183+
## Run on Azure
184+
185+
1. Make sure you are at the repository root.
186+
187+
```bash
188+
cd $REPOSITORY_ROOT
189+
```
190+
191+
1. Login to Azure.
192+
193+
```bash
194+
# Login to Azure Dev CLI
195+
azd auth login
196+
```
197+
198+
1. Check login status.
199+
200+
```bash
201+
# Azure Dev CLI
202+
azd auth login --check-status
203+
```
204+
205+
1. Initialize `azd` template.
206+
207+
```bash
208+
azd init
209+
```
210+
211+
> **NOTE**: You will be asked to provide environment name for provisioning.
212+
213+
1. Set the connector type to `Ollama`.
214+
215+
```bash
216+
azd env set CONNECTOR_TYPE "Ollama"
217+
```
218+
219+
The default model OCP uses is [llama3.2](https://ollama.com/library/llama3.2). If you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, add it to azd environment variables.
220+
221+
```bash
222+
azd env set OLLAMA_MODEL "qwen"
223+
```
224+
225+
2. As a default, the app uses a Serverless GPU with NVIDIA T4 (`NC8as-T4`). If you want to use NVIDIA A100, set the GPU profile.
226+
227+
```bash
228+
azd env set GPU_PROFILE_NAME "NC24-A100"
229+
```
230+
231+
If you want to know more about Serverless GPU, visit [Using serverless GPUs in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/gpu-serverless-overview#use-serverless-gpus).
232+
233+
3. Run the following commands in order to provision and deploy the app.
234+
235+
```bash
236+
azd up
237+
```
238+
239+
> **NOTE**: You will be asked to provide Azure subscription and location for deployment.
240+
> **IMPORTANT**: Due to the limitation for GPU support, the available regions are limited to `Australia East`, `Sweden Central` and `West US 3`. For more details, visit [Using serverless GPUs in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/gpu-serverless-overview#supported-regions).
241+
242+
Once deployed, you will be able to see the deployed OCP app URL.
243+
244+
4. Open your web browser, navigate to the OCP app URL, and enter prompts.
245+
246+
5. Clean up all the resources.
247+
248+
```bash
249+
azd down --force --purge
250+
```

infra/main.parameters.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
"huggingFaceModel": {
4242
"value": "${HUGGING_FACE_MODEL=hf.co/Qwen/Qwen3-0.6B-GGUF}"
4343
},
44+
"ollamaModel": {
45+
"value": "${OLLAMA_MODEL=llama3.2}"
46+
},
4447
"lgModel": {
4548
"value": "${LG_MODEL=hf.co/LGAI-EXAONE/EXAONE-4.0-1.2B-GGUF}"
4649
},

infra/resources.bicep

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,4 @@ module ollama 'br/public:avm/res/app/container-app:0.18.1' = if (useOllama == tr
457457
}
458458

459459
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.loginServer
460-
output AZURE_RESOURCE_OPENCHAT_PLAYGROUNDAPP_ID string = openchatPlaygroundApp.outputs.resourceId
460+
output AZURE_RESOURCE_OPENCHAT_PLAYGROUNDAPP_ID string = openchatPlaygroundApp.outputs.resourceId

src/OpenChat.PlaygroundApp/Abstractions/LanguageModelConnector.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public static async Task<IChatClient> CreateChatClientAsync(AppSettings settings
4242
ConnectorType.DockerModelRunner => new DockerModelRunnerConnector(settings),
4343
ConnectorType.FoundryLocal => new FoundryLocalConnector(settings),
4444
ConnectorType.HuggingFace => new HuggingFaceConnector(settings),
45+
ConnectorType.Ollama => new OllamaConnector(settings),
4546
ConnectorType.LG => new LGConnector(settings),
4647
ConnectorType.OpenAI => new OpenAIConnector(settings),
4748
ConnectorType.Upstage => new UpstageConnector(settings),
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using Microsoft.Extensions.AI;
2+
3+
using OllamaSharp;
4+
5+
using OpenChat.PlaygroundApp.Abstractions;
6+
using OpenChat.PlaygroundApp.Configurations;
7+
8+
using System.Linq;
9+
10+
namespace OpenChat.PlaygroundApp.Connectors;
11+
12+
/// <summary>
13+
/// This represents the connector entity for Ollama.
14+
/// </summary>
15+
public class OllamaConnector(AppSettings settings) : LanguageModelConnector(settings.Ollama)
16+
{
17+
private readonly AppSettings _appSettings = settings ?? throw new ArgumentNullException(nameof(settings));
18+
/// <inheritdoc/>
19+
public override bool EnsureLanguageModelSettingsValid()
20+
{
21+
var settings = this.Settings as OllamaSettings;
22+
if (settings is null)
23+
{
24+
throw new InvalidOperationException("Missing configuration: Ollama.");
25+
}
26+
27+
if (string.IsNullOrWhiteSpace(settings.BaseUrl!.Trim()) == true)
28+
{
29+
throw new InvalidOperationException("Missing configuration: Ollama:BaseUrl.");
30+
}
31+
32+
if (string.IsNullOrWhiteSpace(settings.Model!.Trim()) == true)
33+
{
34+
throw new InvalidOperationException("Missing configuration: Ollama:Model.");
35+
}
36+
37+
return true;
38+
}
39+
40+
/// <inheritdoc/>
41+
public override async Task<IChatClient> GetChatClientAsync()
42+
{
43+
var settings = this.Settings as OllamaSettings;
44+
var baseUrl = settings!.BaseUrl!;
45+
var model = settings!.Model!;
46+
47+
var config = new OllamaApiClient.Configuration
48+
{
49+
Uri = new Uri(baseUrl),
50+
Model = model,
51+
};
52+
53+
var chatClient = new OllamaApiClient(config);
54+
var pulls = chatClient.PullModelAsync(model);
55+
await foreach (var pull in pulls)
56+
{
57+
Console.WriteLine($"Pull status: {pull!.Status}");
58+
}
59+
60+
Console.WriteLine($"The {this._appSettings.ConnectorType} connector created with model: {settings.Model}");
61+
return await Task.FromResult(chatClient).ConfigureAwait(false);
62+
}
63+
}

test/OpenChat.PlaygroundApp.Tests/Abstractions/LanguageModelConnectorTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public void Given_Null_Settings_When_CreateChatClient_Invoked_Then_It_Should_Thr
7575
[Theory]
7676
[InlineData(ConnectorType.Unknown)]
7777
[InlineData(ConnectorType.GoogleVertexAI)]
78-
[InlineData(ConnectorType.Ollama)]
7978
[InlineData(ConnectorType.Anthropic)]
8079
[InlineData(ConnectorType.Naver)]
8180
public void Given_Unsupported_ConnectorType_When_CreateChatClient_Invoked_Then_It_Should_Throw(ConnectorType connectorType)

0 commit comments

Comments
 (0)