当前位置: 首页 > news >正文

SwiftUI-MLX本地大模型开发(二)

介绍

在 SwiftUI-MLX本地大模型开发一文中,我们已经详细讲了如何利用 MLX 进行本地大模型的开发。但是通过案例可以发现 2 个问题:

  1. MLX 内置的大模型数量有限。
  2. 每次大模型都需要从 HuggingFace 下载。

如何解决这 2 个问题,方案是:定制大模型与使用离线大模型。

定制大模型

  • 通过扩展MLXLLM.ModelRegistry实现模型的定制。
  • 可以在 Hugging Face 模型搜索地址 中搜索需要的 MLX 大模型。
// MARK: - 注册自定义模型,模型必须为MLX格式
extension MLXLLM.ModelRegistry {public static let llama3_2_3B_4bit = ModelConfiguration(id: "mlx-community/Llama-3.2-3B-Instruct-4bit", // Hugging Face上模型的仓库路径overrideTokenizer: "PreTrainedTokenizer" // 分词器)
}

使用离线大模型

  • 每次都从 HuggingFace 在线下载模型非常麻烦,如果已经离线下载了模型到本地,可以通过指定路径的方式加载模型。
  • 可以在 Model Scope 模型搜索地址 中搜索并下载需要的 MLX 大模型。
extension MLXLLM.ModelRegistry {public static let localModel = ModelConfiguration(directory: URL(fileURLWithPath: "/Users/yangfan/Documents/modelscope/Llama-3.2-3B-Instruct"),  // 本地模型的路径overrideTokenizer: "PreTrainedTokenizer")
}

使用

struct ContentView: View {// 提示词@State private var prompt: String = "什么是SwiftUI?"// 输出结果@State private var response: String = ""@State private var isLoading: Bool = falsevar body: some View {VStack(spacing: 16) {// 顶部输入区域HStack {TextField("输入提示词...", text: $prompt).textFieldStyle(.roundedBorder).font(.system(size: 16))Button {response = ""Task {do {try await generate()} catch {debugPrint(error)}}} label: {Text("生成").foregroundStyle(.white).padding(.horizontal, 16).padding(.vertical, 8).background(prompt.isEmpty ? Color.gray : Color.blue).cornerRadius(8)}.buttonStyle(.borderless).disabled(prompt.isEmpty || isLoading)}.padding(.horizontal).padding(.top)// 分隔线Rectangle().fill(Color.gray.opacity(0.2)).frame(height: 1)// 响应展示区域if response != "" {ResponseBubble(text: response)}Spacer()}if isLoading {ProgressView().progressViewStyle(.circular).padding()}}
}extension ContentView {// MARK: 文本生成func generate() async throws {isLoading = true// 加载模型//  let modelConfiguration = ModelRegistry.llama3_2_3B_4bitlet modelConfiguration = ModelRegistry.localModellet modelContainer = try await LLMModelFactory.shared.loadContainer(configuration: modelConfiguration) { progress inprint("正在下载 \(modelConfiguration.name),当前进度 \(Int(progress.fractionCompleted * 100))%")}// 生成结果let _ = try await modelContainer.perform { [prompt] context inlet input = try await context.processor.prepare(input: .init(prompt: prompt))let result = try MLXLMCommon.generate(input: input, parameters: .init(), context: context) { tokens inlet text = context.tokenizer.decode(tokens: tokens)Task { @MainActor inself.response = textself.isLoading = false}return .more}return result}}
}struct ResponseBubble: View {let text: Stringvar body: some View {ScrollView {VStack(alignment: .leading, spacing: 8) {Text("AI").font(.system(size: 16)).foregroundColor(.gray)Text(text).font(.system(size: 16)).lineSpacing(4).padding().background(Color.blue.opacity(0.1)).cornerRadius(12)}}.padding(.horizontal)}
}

效果

  • 定制大模型。
定制大模型.gif
  • 使用离线大模型。
使用离线大模型.gif


喜欢的朋友记得点赞、收藏、关注哦!!!

http://www.xdnf.cn/news/271819.html

相关文章:

  • 射频指标互调与交调简略
  • ubuntu使用apt安装软件
  • python中的yield关键字用法
  • 数据赋能(209)——质量管理——时效性原则
  • 文献分享:抗体治疗癌症综述
  • EMMC存储性能测试方法
  • FramePack部署(从PyCharm解释器创建和使用开始)保姆级教程
  • 基于SpringBoot的篮球竞赛预约平台设计与实现
  • 数据赋能(210)——质量管理——可靠性原则
  • FastAPI系列13:API的安全防护
  • 经典算法 最小生成树(prim算法)
  • QT6 源(70):阅读与注释按钮类 QPushButton,及各种属性验证,
  • 返回倒数第k个节点题解
  • 学习黑客分析案例
  • 山东大学计算机组成与设计第九、十章习题解析
  • 延时启动windows中程序
  • C++Primerplus编程练习 第五章
  • 继V1.5之后,幻方又发布了 DeepSeek-Prover-V2-671B,参数提升100倍
  • 【AI平台】n8n入门6:调用MCP服务(非社区节点)
  • 构建灵活的配置管理系统:YAML 与 TOML 的应用与热更新实践
  • 生成树、Prime、Kruskal
  • 第40课 常用快捷操作——按“Tab键”即时更改属性
  • 为什么需要启动探针(StartupProb)?
  • neatchat轻量级丝滑的ai模型web客户端
  • python进阶(2)二进制
  • 文件操作-
  • 【今日三题】游游的重组偶数(模拟) / 体操队形(回溯) / 二叉树中的最大路径和(树形dp)
  • 注入内部Bean
  • C与指针5——字符串合集
  • 高频数据冲击数据库的技术解析与应对方案