Spezi LLM

Build and Test codecov DOI

概述

Spezi LLM Swift 包包含一些模块,这些模块有助于将 LLM 相关的功能集成到您的应用程序中。该包提供了所有必要的工具,用于本地 LLM 执行、使用基于远程 OpenAI 的 LLM,以及在本地网络内的 Fog 节点资源上运行 LLM。

Screenshot displaying the Chat View utilizing the OpenAI API from SpeziLLMOpenAI. Screenshot displaying the Local LLM Download View from SpeziLLMLocalDownload. Screenshot displaying the Chat View utilizing a locally executed LLM via SpeziLLMLocal.
OpenAI LLM 聊天视图 语言模型下载 本地 LLM 聊天视图

设置

1. 添加 Spezi LLM 作为依赖项

您需要在 Xcode 中将 SpeziLLM Swift 包添加到您的应用Swift 包中。

重要提示

如果您的应用程序尚未配置为使用 Spezi,请按照Spezi 设置文章来设置核心 Spezi 基础设施。

2. 按照各个目标的设置步骤进行操作

由于 Spezi LLM 包含各种不同目标,用于特定的 LLM 功能,请按照本 README 中相应目标部分的补充设置指南进行操作。

目标

Spezi LLM 提供了许多目标,以帮助开发人员将 LLM 集成到基于 Spezi 的应用程序中

以下部分重点介绍了 SpeziLLMLocalSpeziLLMOpenAISpeziLLMFog 目标的设置和基本使用,以便将语言模型集成到基于 Spezi 的应用程序中。

注意

要了解有关各个目标用法的更多信息,请参阅该包的 DocC 文档

Spezi LLM 本地

该目标使开发人员能够轻松地在设备本地执行中等大小的语言模型 (LLM)。 该模块允许您通过纯粹基于 Swift 的 API 与本地运行的 LLM 交互,无需与底层代码交互,构建在 SpeziLLM 目标的基础设施之上。

重要提示

Spezi LLM 本地与模拟器不兼容。 底层 mlx-swift 需要现代 Metal MTLGPUFamily,而模拟器不提供该功能。

重要提示

重要提示:要使用 LLM 本地目标,某些 LLM 需要将增加内存限制权限添加到项目中。

设置

您可以在典型的 SpeziAppDelegate 中配置 Spezi 本地 LLM 执行。 在下面的示例中,来自SpeziLLM目标的LLMRunner(负责在 Spezi 生态系统中提供 LLM 功能)配置了来自SpeziLLMLocal目标的LLMLocalPlatform。 这使 LLMRunner 准备好在本地执行语言模型。

class TestAppDelegate: SpeziAppDelegate {
    override var configuration: Configuration {
        Configuration {
            LLMRunner {
                LLMLocalPlatform()
            }
        }
    }
}

SpeziLLMLocalDownload 可用于从 HuggingFace 下载 LLM 并将其保存在设备上以供执行。 LLMLocalDownloadView 提供了一个开箱即用的引导视图,用于在本地下载模型。

struct LLMLocalOnboardingDownloadView: View {
    var body: some View {
        LLMLocalDownloadView(
            model: .llama3_8B_4bit,
            downloadDescription: "The Llama3 8B model will be downloaded",
        ) {
            // Action to perform after the model is downloaded and the user presses the next button.
        }
    }
}

提示

可以使用 SpeziOnboarding 将 LLMLocalDownloadView 视图包含在您的引导流程中,如本示例中所示

用法

下面的代码示例展示了通过SpeziLLM LLMRunner与本地 LLM 的交互,该交互通过上面显示的Configuration注入到 SwiftUI Environment中。

LLMLocalSchema 定义了要执行的 LLMLocalSession 的类型和配置。 此转换是通过使用 LLMLocalPlatformLLMRunner 完成的。 通过 LLMLocalSession/generate() 进行的推理返回一个 AsyncThrowingStream,它产生所有生成的 String 片段。

struct LLMLocalDemoView: View {
    @Environment(LLMRunner.self) var runner
    @State var responseText = ""

    var body: some View {
        Text(responseText)
            .task {
                // Instantiate the `LLMLocalSchema` to an `LLMLocalSession` via the `LLMRunner`.
                let llmSession: LLMLocalSession = runner(
                    with: LLMLocalSchema(
                        model: .llama3_8B_4bit,
                    )
                )

                do {
                    for try await token in try await llmSession.generate() {
                        responseText.append(token)
                    }
                } catch {
                    // Handle errors here. E.g., you can use `ViewState` and `viewStateAlert` from SpeziViews.
                }
            }
    }
}

可以使用LLMChatViewSchema轻松地为您的带有本地 LLM 的聊天机器人应用程序创建一个对话式聊天界面。

struct LLMLocalChatView: View {
    var body: some View {
        LLMChatViewSchema(
            with: LLMLocalSchema(
                model: .llama3_8B_4bit
            )
        )
    }
}

注意

要了解有关 SpeziLLMLocal 用法的更多信息,请参阅全面的 DocC 文档

Spezi LLM Open AI

该模块允许您在 Spezi 应用程序中与 OpenAI 的基于 GPT 的大型语言模型 (LLM) 进行交互。 SpeziLLMOpenAI 提供了一个纯粹基于 Swift 的 API,用于与 OpenAI GPT API 进行交互,构建在 SpeziLLM 目标的基础设施之上。 此外,SpeziLLMOpenAI 为开发人员提供了一种声明式特定领域语言,以利用 OpenAI 函数调用机制。 这实现了 OpenAI LLM 和外部工具(例如 Spezi 生态系统)之间的结构化、双向和可靠的通信。

设置

为了在 Spezi 生态系统中使用 OpenAI LLM,需要在 Spezi Configuration 中使用 LLMOpenAIPlatform 初始化 SpeziLLM LLMRunner。 只有在此之后,LLMRunner 才能用于 OpenAI LLM 的推理。 有关更多详细信息,请参阅 SpeziLLM 文档

import Spezi
import SpeziLLM
import SpeziLLMOpenAI

class LLMOpenAIAppDelegate: SpeziAppDelegate {
    override var configuration: Configuration {
        Configuration {
            LLMRunner {
                LLMOpenAIPlatform()
            }
        }
    }
}

重要提示

如果在 macOS 上使用 SpeziLLMOpenAI,请确保通过PROJECT_NAME > Signing&Capabilities > + CapabilityKeychain Access Groups 权限添加到封闭的 Xcode 项目中。 密钥链组的数组可以留空,只需要基本权限。

用法

下面的代码示例展示了通过SpeziLLM LLMRunner与 OpenAI LLM 的交互,该交互通过上面显示的Configuration注入到 SwiftUI Environment中。

LLMOpenAISchema 定义了要执行的 LLMOpenAISession 的类型和配置。 此转换是通过使用 LLMOpenAIPlatformLLMRunner 完成的。 通过 LLMOpenAISession/generate() 进行的推理返回一个 AsyncThrowingStream,它产生所有生成的 String 片段。

import SpeziLLM
import SpeziLLMOpenAI
import SwiftUI

struct LLMOpenAIDemoView: View {
    @Environment(LLMRunner.self) var runner
    @State var responseText = ""

    var body: some View {
        Text(responseText)
            .task {
                // Instantiate the `LLMOpenAISchema` to an `LLMOpenAISession` via the `LLMRunner`.
                let llmSession: LLMOpenAISession = runner(
                    with: LLMOpenAISchema(
                        parameters: .init(
                            modelType: .gpt4_o,
                            systemPrompt: "You're a helpful assistant that answers questions from users.",
                            overwritingToken: "abc123"
                        )
                    )
                )

                do {
                    for try await token in try await llmSession.generate() {
                        responseText.append(token)
                    }
                } catch {
                    // Handle errors here. E.g., you can use `ViewState` and `viewStateAlert` from SpeziViews.
                }
            }
    }
}

注意

要了解有关 SpeziLLMOpenAI 用法的更多信息,请参阅 DocC 文档

Spezi LLM Fog

SpeziLLMFog 目标使您能够使用在本地网络内的 Fog 节点计算资源上运行的 LLM。 Fog 节点通过 mDNS 宣传其服务,使客户端能够发现本地网络内为特定主机提供服务的所有 Fog 节点。 然后,SpeziLLMFog 将 LLM 推理作业动态地分派到本地网络内的随机 Fog 节点,并流式传输响应以将其呈现给用户。

重要提示

SpeziLLMFog 需要本地网络内的 SpeziLLMFogNode,该节点托管在一些实际执行推理请求的计算资源上。 SpeziLLMFog 提供了基于 Docker 的 SpeziLLMFogNode 包,可以轻松设置这些 Fog 节点。 有关更多详细信息,请参阅 SPM 包根目录下的 FogNode 目录以及相应的 README.md

设置

为了在 Spezi 生态系统中使用 Fog LLM,需要在 Spezi Configuration 中使用 LLMFogPlatform 初始化 SpeziLLM LLMRunner。 只有在此之后,LLMRunner 才能用于 Fog LLM 的推理。 有关更多详细信息,请参阅 SpeziLLM 文档LLMFogPlatform 需要使用用于签署 Fog 节点 Web 服务证书的自定义根 CA 证书进行初始化(有关更多信息,请参阅 FogNode/README.md 文档)。 使用 SpeziLLMFog 将根 CA 证书从 Fog 节点复制为资源到应用程序,并使用它在 Spezi Configuration 中初始化 LLMFogPlatform

class LLMFogAppDelegate: SpeziAppDelegate {
    private nonisolated static var caCertificateUrl: URL {
        // Return local file URL of root CA certificate in the `.crt` format
    }
    
    override var configuration: Configuration {
         Configuration {
             LLMRunner {
                // Set up the Fog platform with the custom CA certificate
                LLMRunner {
                    LLMFogPlatform(configuration: .init(caCertificate: Self.caCertificateUrl))
                }
            }
        }
    }
}

用法

下面的代码示例展示了通过SpeziLLM LLMRunner与 Fog LLM 的交互,该交互通过上面显示的Configuration注入到 SwiftUI Environment中。

LLMFogSchema 定义了要执行的 LLMFogSession 的类型和配置。 此转换是通过使用 LLMFogPlatformLLMRunner 完成的。 通过 LLMFogSession/generate() 进行的推理返回一个 AsyncThrowingStream,它产生所有生成的 String 片段。 LLMFogSession 在设置后会自动发现本地网络中的所有可用 LLM Fog 节点,并将 LLM 推理作业分派到 Fog 计算资源,流式传输响应并将其呈现给用户。

重要提示

LLMFogSchema 接受一个闭包,该闭包返回一个授权令牌,该令牌通过 LLMFogParameters/init(modelType:systemPrompt:authToken:) 与每个请求一起传递到 Bearer HTTP 字段中的 Fog 节点。 每次 LLM 推理请求时,都会通过闭包创建令牌,因为 LLMFogSession 可能会持续很长时间,因此令牌可能会过期。 确保闭包适当地缓存令牌,以防止不必要的令牌刷新往返于外部系统。

struct LLMFogDemoView: View {
    @Environment(LLMRunner.self) var runner
    @State var responseText = ""

    var body: some View {
        Text(responseText)
            .task {
                // Instantiate the `LLMFogSchema` to an `LLMFogSession` via the `LLMRunner`.
                let llmSession: LLMFogSession = runner(
                    with: LLMFogSchema(
                        parameters: .init(
                            modelType: .llama7B,
                            systemPrompt: "You're a helpful assistant that answers questions from users.",
                            authToken: {
                                // Return authorization token as `String` or `nil` if no token is required by the Fog node.
                            }
                        )
                    )
                )

                do {
                    for try await token in try await llmSession.generate() {
                        responseText.append(token)
                    }
                } catch {
                    // Handle errors here. E.g., you can use `ViewState` and `viewStateAlert` from SpeziViews.
                }
            }
    }
}

注意

要了解有关 SpeziLLMFog 用法的更多信息,请参阅 DocC 文档

贡献

欢迎对此项目做出贡献。 请务必先阅读贡献指南贡献者盟约行为准则

许可证

此项目已获得 MIT 许可证的许可。 有关更多信息,请参阅 许可证

Spezi Footer Spezi Footer