Back to blog
    移动应用的端侧文本分类
    text classificationon-device AImobile AINLPimplementationsegment:mobile-builder

    移动应用的端侧文本分类

    如何构建在用户手机上运行的快速、准确的文本分类。情感分析、内容分类、意图检测和垃圾信息过滤,无需API调用。

    EErtas Team·

    文本分类是最实用的端侧AI功能。它速度快(100ms以内)、准确(微调后90%+)、在最小的模型(1B)上也能工作,并且可以在几乎任何现代手机上运行。

    如果你的应用需要对内容分类、检测意图、过滤垃圾信息、分析情感或路由消息,端侧分类是最高效的方案。

    为什么分类是端侧的理想场景

    分类具有使其完美适合移动端的特性:

    输出简短: 模型生成单个词或短语(类别标签)。这只需毫秒,而非秒级。

    小模型即可胜任: 微调后的1B模型处理分类可达到90-94%的准确率。不需要更大、更慢的模型。

    高频调用: 分类常常在每段内容上运行(每条消息、每条笔记、每段图片描述)。在高频下,云API成本快速累积。在端侧,每次分类都是免费的。

    后台兼容: 分类可以在无需用户交互的情况下在后台运行。输入费用时自动分类。保存笔记时自动标注。收到消息时自动检测垃圾信息。

    分类用例

    情感分析

    判断用户输入的情感倾向。适用于:

    • 客户反馈应用(正面/负面/中性)
    • 社交媒体监控
    • 日记/情绪追踪应用
    • 支持工单优先级路由

    内容分类

    自动为用户内容分配类别:

    • 费用分类(餐饮、交通、娱乐、公共事业)
    • 笔记标注(工作、个人、创意、参考)
    • 邮件分类(重要、通讯、社交、事务性)
    • 照片相册整理(旅行、美食、人物、自然)

    意图检测

    理解用户想要做什么:

    • 语音助手路由(播放音乐、设置定时器、发送消息、搜索)
    • 聊天机器人意图分类(提问、投诉、请求退款)
    • 搜索查询分类(导航、信息、交易)

    内容过滤

    检测并过滤不需要的内容:

    • 消息应用中的垃圾信息检测
    • 不当内容标记
    • 社区应用中的偏离主题消息检测

    语言检测

    识别输入文本的语言,用于多语言应用。路由到合适的模型或翻译流程。

    实现

    提示词模式

    对于基于LLM的分类,提示词很简单:

    Classify the following text into one of these categories: [Food, Transport, Entertainment, Utilities, Shopping, Healthcare, Other]
    
    Text: "Uber ride to airport"
    Category:
    

    模型生成单个词: "Transport"

    微调用于分类

    以聊天格式创建训练样本:

    {"messages": [
      {"role": "user", "content": "Classify: Uber ride to airport"},
      {"role": "assistant", "content": "Transport"}
    ]}
    
    {"messages": [
      {"role": "user", "content": "Classify: Netflix monthly subscription"},
      {"role": "assistant", "content": "Entertainment"}
    ]}
    
    {"messages": [
      {"role": "user", "content": "Classify: Grocery store visit"},
      {"role": "assistant", "content": "Food"}
    ]}

    使用涵盖所有类别的500-1,000个样本,微调后的1B模型可达到90-94%的准确率。这超过了带提示词的GPT-4o在同一任务上的表现(通常78-85%)。

    结构化输出

    为了可靠地解析,指示模型输出JSON:

    {"messages": [
      {"role": "user", "content": "Classify this expense: Uber ride to airport\nOutput JSON with 'category' and 'confidence' fields."},
      {"role": "assistant", "content": "{\"category\": \"Transport\", \"confidence\": \"high\"}"}
    ]}

    微调后的模型学会产生一致的JSON。在你的应用代码中直接解析输出。

    速度优化

    分类只生成很少的token(1-10个)。你可以为最大吞吐量进行优化:

    • n_predict设置为较低值(最多10-20 tokens)
    • 使用stop tokens在类别标签后停止生成
    • 使用temperature 0获得确定性输出
    • 处理列表时批量分类

    通过这些优化,1B模型在旗舰手机上每秒可分类5-15个项目。

    性能预期

    按训练数据量的准确率

    训练样本数1B准确率3B准确率
    10078-82%82-86%
    25084-88%87-91%
    50088-92%91-94%
    1,00090-94%93-96%
    2,00092-95%94-97%

    大多数分类任务在1,000个样本以上收益递减。从500开始,仅在准确率不足时再添加更多。

    按设备的速度

    设备1B分类时间每秒分类数
    iPhone 16 Pro30-60ms15-30
    iPhone 1450-80ms12-20
    Galaxy S2440-70ms14-25
    中端Android80-130ms8-12

    每次分类在任何现代手机上都在150ms以内完成。用户感知为即时。

    与云API的对比

    指标云API端侧1B (微调后)
    延迟500-2,000ms30-130ms
    准确率 (领域)78-85% (提示词)90-94% (微调)
    每次分类成本$0.00003-0.0003$0
    离线
    隐私数据发送给第三方端侧处理

    端侧在分类的每个指标上都获胜: 更快、更准确(微调后)、免费、离线可用且私密。

    架构模式

    后台分类服务

    对于需要自动分类内容的应用:

    // Android: 后台分类
    class ClassificationService {
        private val model: LlamaModel = LlamaModel()
    
        fun classifyExpense(description: String): ExpenseCategory {
            val prompt = "Classify: $description"
            val result = model.generate(prompt, maxTokens = 10, temperature = 0f)
            return ExpenseCategory.fromString(result.trim())
        }
    
        fun classifyBatch(items: List<String>): List<ExpenseCategory> {
            return items.map { classifyExpense(it) }
        }
    }

    实时分类

    对于用户输入时即分类的功能(输入费用时自动建议类别):

    // iOS: 带防抖的实时分类
    class ClassificationViewModel: ObservableObject {
        @Published var suggestedCategory: String = ""
        private var classifyTask: Task<Void, Never>?
    
        func onTextChanged(_ text: String) {
            classifyTask?.cancel()
            classifyTask = Task {
                try? await Task.sleep(nanoseconds: 300_000_000) // 300ms防抖
                guard !Task.isCancelled else { return }
                let category = await classifier.classify(text)
                await MainActor.run { suggestedCategory = category }
            }
        }
    }

    开始使用

    1. 定义你的类别。 列出分类器应产生的5-20个标签。
    2. 创建训练样本。 至少500个样本,覆盖所有类别和真实输入。
    3. 微调1B模型。 使用Ertas等平台: 上传你的样本,选择1B基础模型,使用LoRA训练,导出GGUF。
    4. 集成llama.cpp。 将推理库添加到你的iOS或Android项目中。
    5. 在真实数据上测试。 通过模型运行你的评估集。目标90%+准确率。
    6. 部署。 将模型打包或通过安装后下载交付。

    分类是通往生产级端侧AI的最快路径。模型小巧,任务简单,结果在领域特定类别上可衡量地优于云API。

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading