在 SwiftUI-MLX本地大模型开发、SwiftUI-MLX本地大模型开发(二)与 SwiftUI-MLX本地大模型开发(三)中,我们解决了基本使用、定制模型、使用本地模型、更改模型存储路径、转换模型、iPad运行等问题,但使用的都是别人训练好的模型。本文将介绍,如何基于一个通用 LLM 进行微调,使该模型成为个人的“专属”模型。
pip install mlx
pip install mlx-lm
pip install transformers
train.jsonl
、valid.jsonl
与test.jsonl
,分别用于训练、验证与测试。ticoAg/Chinese-medical-dialogue
进行微调。{"text": "你是谁?\n我是你的私人智能小助手,我叫羊羊。"}
{"text": "地球有多大?\n地球的半径大约是6371公里。"}
...
--model
、--data
、--adapter-path
等参数。adapters
目录下生成多个.safetensors
文件。mlx_lm.lora \
--train \
--model /Users/yangfan/Documents/huggingface/models/mlx-community/Llama-3.2-1B-Instruct-4bit \
--adapter-path /Users/yangfan/Desktop/adapters \
--data /Users/yangfan/Desktop/Data \
--batch-size 1 \
mlx_lm.fuse \
--model /Users/yangfan/Documents/huggingface/models/mlx-community/Llama-3.2-1B-Instruct-4bit \
--adapter-path /Users/yangfan/Desktop/adapters \
--save-path /Users/yangfan/Desktop/Llama-3.2-1B-Instruct-4bit-fused # 新模型目录
import MLXLLM
import MLXLMCommon
import SwiftUI
// MARK: - 注册自定义模型
extension MLXLLM.ModelRegistry {
public static let localModel = ModelConfiguration(
directory: URL(fileURLWithPath: "/Users/yangfan/Desktop/Llama-3.2-1B-Instruct-4bit-fused"),
overrideTokenizer: "PreTrainedTokenizer",
defaultPrompt: ""
)
}
struct ContentView: View {
// 提示词
@State private var prompt: String = "小孩扁桃体炎总哭饮食注意点是什么?"
// 输出结果
@State private var response: String = ""
@State private var isLoading: Bool = false
var 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.localModel
let modelContainer = try await LLMModelFactory.shared.loadContainer(configuration: modelConfiguration) { progress in
print("正在下载 \(modelConfiguration.name),当前进度 \(Int(progress.fractionCompleted * 100))%")
}
// 生成结果
let _ = try await modelContainer.perform { [prompt] context in
let input = try await context.processor.prepare(input: .init(prompt: prompt))
let result = try MLXLMCommon.generate(input: input, parameters: .init(), context: context) { tokens in
let text = context.tokenizer.decode(tokens: tokens)
Task { @MainActor in
self.response = text
self.isLoading = false
}
return .more
}
return result
}
}
}
struct ResponseBubble: View {
let text: String
var 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
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有