发布于 2026-01-06 0 阅读
0

构建 Ollama Cloud——将本地推理扩展到云端

构建 Ollama Cloud——将本地推理扩展到云端

Ollama 主要是一个封装库llama.cpp,专为本地推理任务而设计。如果您追求极致的性能或丰富的功能,它通常不是您的首选,但它也有其用途,尤其是在需要考虑外部依赖项的环境中。

本地人工智能开发

使用 Ollama 进行本地 AI 开发时,设置简单高效。开发者通常利用 Ollama 直接在本地机器上运行推理任务。下图展示了使用 Ollama 的典型本地开发设置:

奥拉玛的典型本地开发

这种配置使开发人员能够快速测试和迭代,而无需处理复杂的远程服务器通信。它非常适合初始原型设计和开发阶段,因为在这些阶段,快速迭代至关重要。

从本地到云端

从本地部署过渡到可扩展的云环境,意味着从简单的 1:1 设置(一个用户请求对应一个推理主机)演变为更复杂的多对多配置(多个用户请求对应多个推理主机)。这种转变对于在需求增长的情况下保持效率和响应能力至关重要。

以下是从本地开发到生产环境扩展的扩展方式:

典型的m:n缩放视图

在此过渡期间采用简单直接的方法会显著增加应用程序的复杂性,尤其是在会话需要在不同状态下保持一致的情况下。如果请求没有被最优地路由到最佳的可用推理主机,则可能会出现延迟和效率低下。

此外,分布式应用程序的复杂性使得在本地进行测试变得困难,这可能会减慢开发过程并增加生产环境中出现故障的风险。

无服务器

无服务器计算抽象化了服务器管理和基础设施细节,使开发人员能够专注于代码和业务逻辑。通过将请求处理和一致性维护与应用程序解耦,无服务器架构简化了扩展。

这种方法可以让应用程序专注于提供价值,解决许多常见的扩展性挑战,而不会给开发人员带来基础设施复杂性的负担。

WebAssembly

WebAssembly (Wasm) 通过将应用程序编译成自包含的模块来解决依赖管理难题。这使得应用程序更容易在本地和云端进行编排和测试,从而确保不同环境之间的一致性。

τ

Tau 是一个用于构建低维护、高可扩展云计算平台的框架。它以简洁性和可扩展性著称。Tau 简化了部署流程,并支持运行本地云进行开发,从而可以对云基础设施及其上运行的应用程序进行端到端 (E2E) 测试。

Taubyte 将这种方法称为“本地编码等于全球生产”,它确保本地有效的方法在全球范围内也有效,从而大大简化了开发和部署过程。

将 Ollama 集成到 Tau 的 Orbit 插件系统中

Tau 的插件系统 Orbit 通过将服务封装到 WebAssembly 宿主模块中,显著简化了将服务转换为可管理组件的过程。这种方法使 Tau 能够接管编排职责,从而简化部署和管理流程。

在 Ollama 中导出函数

为了让 Ollama 函数能够在 Tau 生态系统中使用,我们利用 Orbit 系统将 Ollama 的功能导出为可调用的端点。以下是在 Go 中导出端点的方法:



func (s *ollama) W_pull(ctx context.Context, module satellite.Module, modelNamePtr uint32, modelNameSize uint32, pullIdptr uint32) Error {
    model, err := module.ReadString(modelNamePtr, modelNameSize)
    if err != nil {
        return ErrorReadMemory
    }

    id, updateFunc := s.getPullId(model)

    if updateFunc != nil {
        go func() {
            err = server.PullModel(s.ctx, model, &server.RegistryOptions{}, updateFunc)
            s.pullLock.Lock()
            defer s.pullLock.Unlock()
            s.pulls[id].err = err
        }()
    }

    module.WriteUint64(pullIdptr, id)

    return ErrorNone
}


Enter fullscreen mode Exit fullscreen mode

有关导出函数的简单示例,您可以参考hello_world 示例

这些函数一旦定义完成,现在可以通过调用satellite.Export,从而实现 Ollama 与 Tau 环境的无缝集成:



func main() {
    server := new(context.TODO(), "/tmp/ollama-wasm")
    server.init()
    satellite.Export("ollama", server)
}


Enter fullscreen mode Exit fullscreen mode

为 Ollama 插件编写测试

测试该插件的过程非常简化和直接。以下是如何用 Go 编写无服务器函数测试:



//export pull
func pull() {
    var id uint64
    err := Pull("gemma:2b-instruct", &id)
    if err != 0 {
        panic("failed to call pull")
    }
}


Enter fullscreen mode Exit fullscreen mode

使用 Tau 的测试套件和 Go 构建器工具,您可以构建插件,将其部署到测试环境中,并执行无服务器函数来验证其功能:



func TestPull(t *testing.T) {
ctx := context.Background()

<span class="c">// Create a testing suite to test the plugin</span>
<span class="n">ts</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">suite</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>

<span class="c">// Use a Go builder to build plugins and wasm</span>
<span class="n">gob</span> <span class="o">:=</span> <span class="n">builder</span><span class="o">.</span><span class="n">New</span><span class="p">()</span>

<span class="c">// Build the plugin from the directory</span>
<span class="n">wd</span><span class="p">,</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">os</span><span class="o">.</span><span class="n">Getwd</span><span class="p">()</span>
<span class="n">pluginPath</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">gob</span><span class="o">.</span><span class="n">Plugin</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">Join</span><span class="p">(</span><span class="n">wd</span><span class="p">,</span> <span class="s">"."</span><span class="p">),</span> <span class="s">"ollama"</span><span class="p">)</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>

<span class="c">// Attach plugin to the testing suite</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">ts</span><span class="o">.</span><span class="n">AttachPluginFromPath</span><span class="p">(</span><span class="n">pluginPath</span><span class="p">)</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>

<span class="c">// Build a wasm file from serverless function</span>
<span class="n">wasmPath</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">gob</span><span class="o">.</span><span class="n">Wasm</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">path</span><span class="o">.</span><span class="n">Join</span><span class="p">(</span><span class="n">wd</span><span class="p">,</span> <span class="s">"fixtures"</span><span class="p">,</span> <span class="s">"pull.go"</span><span class="p">),</span> <span class="n">path</span><span class="o">.</span><span class="n">Join</span><span class="p">(</span><span class="n">wd</span><span class="p">,</span> <span class="s">"fixtures"</span><span class="p">,</span> <span class="s">"common.go"</span><span class="p">))</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>

<span class="c">// Load the wasm module and call the function</span>
<span class="n">module</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">ts</span><span class="o">.</span><span class="n">WasmModule</span><span class="p">(</span><span class="n">wasmPath</span><span class="p">)</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>

<span class="c">// Call the "pull" function from our wasm module</span>
<span class="n">_</span><span class="p">,</span> <span class="n">err</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">Call</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="s">"pull"</span><span class="p">)</span>
<span class="n">assert</span><span class="o">.</span><span class="n">NilError</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
Enter fullscreen mode Exit fullscreen mode

}

Enter fullscreen mode Exit fullscreen mode




代码

您可以在这里找到完整的代码:https://github.com/ollama-cloud/ollama-as-wasm-plugin/tree/main/tau

接下来是什么?

现在您可以轻松构建LLM应用程序。以下是入门步骤:

  • 从本地开始dream:设置本地环境以开发和测试应用程序。
  • 创建项目:使用 Tau 开始一个新项目,以充分发挥其潜力。
  • 创建生产云:将您的项目部署到生产云环境中。
  • 将插件二进制文件放入该/tb/plugins文件夹。
  • 将您的项目导入生产环境
  • 炫耀!
文章来源:https://dev.to/samyfodil/building-ollama-cloud-scaling-local-inference-to-the-cloud-2i1a