А АMonday, 17 February 2025

Ollama-сервер и API

course
Всем привет.

LLM-модель - это языковая модель, обученная на больших объемах данных. Она помогает в обработке естественного языка для генерации текста на основе предыдущего контекста. LLM также используют в машинном переводе и при автозаполнении текста.

На рынке уже есть решения для работы с моделями с открытым исходным кодом, такие как gpt4all. Для администраторов, девопсов и безопасников подобный инструмент почти бесполезен, так как мы не можем удобно предоставить его разработчикам и контролировать учетные записи пользователей.

А проект Ollama прекрасно решает эти проблемы. И что особенно удобно его можно использовать локально на своем хосте если достаточно VRAM, или в своей локальной сети развернув на одном из серверов компании, и даже дома.

Основные отличия Ollama от других проектов - это предоставление бесплатного API. Уже есть огромный выбор графических интерфейсов для этого API. Проект доведен до ума и не требует танцев с бубном при запуске. Проект поддерживает Windows, Linux и MacOS. Многочисленные инструкции по локальной установке Ollama доступны в сети.

Самый популярный вариант это docker плюс Open WebUI. Суть в том, что сервер лучше запускать в Docker, так как это готовый проект на React и у него есть официальный образ. Также есть и официальный чарт от Open WebUI. 

Но не спешите так делать! Ну право, из-за одного сервиса я буду разворачивать у себя еще и docker. Нет, не буду, и штатно инсталировать Ollama тоже не буду. Не доверяю я всяким инсталяторам.)

И как же тогда? А я возьму из репозитория Ollama его портабельный вариант, и просто разверну его в отдельную папку. Готово! Забегая наперед, перед первым стартом  я пропишу еще две системные переменные для Ollama-сервера чтобы к нему можно было обращаться по локальной сети

OLLAMA_HOST=192.168.1.100

и отдельную папку для моделей чтобы файлы не падали на диск "С"

OLLAMA_MODELS=Е:\ollama\models

Пока все! Запускаю OLLAMA-сервер bat-файлом:

@echo off

start /B ollama.exe serve

timeout /t 5

@echo Load model to server ...

ollama.exe run "gemma:latest"

pause

olama

Если вы заранее не загружали модель набирая ollama.exe pull "gemma:latest", то первый старт до готовности отвечать на запросы у вас займет некоторое время. Проверить работу и наличие локальных моделей можно через запрос http://192.168.1.100:11434/api/tags

Окно командного процессора мне служит как консоль Ollama-севера для контроля его работы. По идее далее для общения с Ollama-сервером я должен запустить еще одну консоль в режиме командного диалога и работать с сервером. Кстати список доступных команд напоминает мне тот самый docker контейнер. 

Но мне удобнее все делать удаленно, потому я написал себе, нет, не аналог Open WebUI, а простой диалог через API. Пример простого АРІ-запроса на Python ниже:

import requests

import json

API_URL = "http://192.168.1.100:11434/api/generate"

MODEL   = "gemma:latest"

PROMPT  = "Capital city of Ukraine?"

payload = {

    "model": MODEL,

    "prompt": PROMPT,

    "stream": False,

    "Content-Type": "application/json"

}

response = requests.post(API_URL, json=payload)

jsondata = json.loads(response.text)

print(jsondata['response'])


Но чем Powershell хуже? И я решил переписать код что выше на более удобный вариант. Теперь мой код поддерживает смену моделей и историю общения:

$ollamaUrl = "http://192.168.1.100:11434"

$logFile = "C:\TMP\Ollama_Chat.txt"

$history = @()

# Функція отримання списку доступних моделей

function Get-Models {

    try {

        $modelsResponse = Invoke-RestMethod -Uri "$ollamaUrl/api/tags" -Method Get

        return $modelsResponse.models.name

    }

    catch {

        Write-Host "Помилка отримання списку моделей: $_"

        return @()

    }

}

# Функція вибору моделі

function Select-Model {

    $models = Get-Models

    if ($models.Count -eq 0) {

        Write-Host "Немаэ доступних моделей."

        exit

    }

    Write-Host "`nДоступні моделі Ollama:"

    for ($i = 0; $i -lt $models.Count; $i++) {

        Write-Host "$($i + 1). $($models[$i])"

    }

    do {

        $choice = Read-Host "Введіть номер моделі"

        if ($choice -match "^\d+$" -and [int]$choice -ge 1 -and [int]$choice -le $models.Count) {

            return $models[[int]$choice - 1]

        }

        Write-Host "Некоректний вибір, спробуйте ще раз."

    } while ($true)

}


# Вибір початкової моделі

$model = Select-Model

Write-Host "`nВибрано модель: $model"

Write-Host "`nВведіть 'exit' для завершення діалогу або 'change' для вибору іншої моделі."

do {

    $userInput = Read-Host "QUERY"


    if ($userInput -eq "exit") {

        Write-Host "`nДіалог завершено. Історію збережено у $logFile"

        break

    }

    if ($userInput -eq "change") {

        $model = Select-Model

        Write-Host "`nМодель змінено на: $model"

        continue

    }

    # Додаємо введене користувачем повідомлення у історію

    $history += @{role="QUERY"; message=$userInput}

    $body = @{

    model = $model

    prompt = $userInput

    temperature = 0.7

    max_tokens = 250

    stream = $false

} | ConvertTo-Json -Depth 10

     

    try {

    $response = Invoke-RestMethod -Uri "$ollamaUrl/api/generate" -Method Post -Body $body -ContentType "application/json"

# Перевірка на пусто

if ($response.Content) {

    $responseJson = $response.Content | ConvertFrom-Json

    Write-Host "`n---- Повна відповідь сервера ----"

    Write-Host ($responseJson | ConvertTo-Json -Depth 10)

    Write-Host "----------------------------"

    $responseJson

} else {

    Write-Host "Відповідь сервера порожня."

}


        # Додаємо відповідь Ollama у історію

        $history += @{role="ANSWER"; message=$response.response}

        # Виводимо діалог

        Write-Host "`n----- Історія діалогу -----"

        foreach ($msg in $history) {

            Write-Host "$($msg.role): $($msg.message)`n"

        }

    }

    catch {

        Write-Host "Помилка запиту: $_"

    }

} while ($true)

# Збереження історії у файл

$historyText = ""

foreach ($msg in $history) {

    $historyText += "$($msg.role): $($msg.message)`r`n"

}


# Якщо файл існує, завантажуємо історію з нього

if (Test-Path $logFile) {

    $history = Get-Content $logFile -Encoding UTF8

} else {

    $history = @()  # Якщо файл не існує, ініціалізуємо порожній масив

}

# Отримуємо поточну дату та час

$currentDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

$history += $currentDate,":" 

$history += $historyText

$history | Out-File -FilePath $logFile -Encoding UTF8


Кстати, если вас не устраивает порт 11434 по умолчаню то переменной OLLAMA_HOST допишите в конец другое значение, например так: 127.0.0.1:11435.

Ну, а если все таки нужен GUI, то  LM Studio будет для вас лучшим выбором.

Удачи.

1 comment:

blank
Anonymous said...

К сожалению OLLAMA не дает воспользоваться моделями другим приложениям.

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное