中宏安科技 大模型训练工程师 一面

1.自我介绍

2. 文章分类大概有多少文章?数据规模怎么影响方案?

答案:

如果文章量只有几千篇,我一般不会一上来就训练很复杂的模型,而是先用预训练模型微调,或者用 embedding 加传统分类器做一个强 baseline。因为数据量太小的时候,复杂模型很容易过拟合,线上效果不稳定。

如果有几十万到几百万篇文章,就可以考虑训练一个更稳定的分类模型,包括 BERT 微调、领域继续预训练、层级分类模型,甚至做多任务学习。数据量越大,越要关注标签噪声,因为文章分类里的标注经常不是绝对干净的,尤其是多维度分类,一个文档可能同时属于多个业务类别。

实际项目里我会先看三个东西:类别数量、每个类别样本分布、单篇文档长度。因为分类方案不是只由文章数量决定的,文档长度和标签体系对模型设计影响更大。

3. 文章自动分类具体是怎么做的?整体链路怎么实现?

答案:

文章分类一般不会直接从文件进模型,而是先做文档解析,把 Word、PDF、HTML、TXT 等格式统一转成结构化文本。然后做清洗、去噪、分段,提取标题、摘要、正文、目录、章节名等字段,再进入分类模型。

如果是短文档,可以直接用 BERT 类模型做分类。如果是长文档,就会先切 chunk,每个 chunk 单独编码,然后把 chunk 级别的表示再聚合成文档级表示,最后做分类。线上一般还会加规则兜底,比如标题里出现非常强的业务关键词时,可以提高某个类别的权重。

代码上,一个简单的文本分类流程大概是这样:

from transformers import AutoTokenizer, AutoModel
import torch
import torch.nn as nn

class DocClassifier(nn.Module):
    def __init__(self, model_name, num_labels):
        super().__init__()
        self.encoder = AutoModel.from_pretrained(model_name)
        self.dropout = nn.Dropout(0.1)
        self.classifier = nn.Linear(self.encoder.config.hidden_size, num_labels)

    def forward(self, input_ids, attention_mask):
        outputs = self.encoder(input_ids=input_ids, attention_mask=attention_mask)
        cls = outputs.last_hidden_state[:, 0, :]
        logits = self.classifier(self.dropout(cls))
        return logits

这个只适合短文本或者截断后的文本。如果文档很长,就不能只靠这个结构。

4. 用 BERT 做文章分类时,是把整篇文章都放进去吗?

答案:

一般不会。BERT 的输入长度通常是 512 token,中文文章稍微长一点就会超过这个长度。如果直接截断,只保留前 512 个 token,可能会丢掉正文后面的关键信息。比如合同、标书、审计报告、技术文档,重要结论不一定在开头。

比较常见的做法是把文章切成多个 chunk,每个 chunk 送进 BERT 得到一个向量,然后再把这些 chunk 向量聚合成文档向量。聚合方式可以是 mean pooling、max pooling、attention pooling,也可以用一个上层 Transformer 建模 chunk 之间的关系。

简单实现如下:

def split_text(text, max_len=400, stride=100):
    chunks = []
    start = 0
    while start < len(text):
        chunks.append(text[start:start + max_len])
        start += max_len - stride
    return chunks

这里用 stride 是为了避免切分边界把一句话或者一个关键信息截断。实际业务里还会优先按标题、段落、章节来切,而不是纯按长度切。

5. 如果 Word 文档有多个分类维度,自动分类应该怎么做?

答案:

多维度文档分类一般不是单标签分类,而是多任务或者多标签问题。比如一个文档既要判断所属业务线,又要判断文档类型,还要判断风险等级、保密等级、适用部门,这些维度之间可能有关联,但不能简单合成一个超大类别。

我会倾向于共享一个文档编码器,然后每个维度接一个独立分类头。这样底层语义表示可以共享,上层每个任务单独学习自己的标签空间。比如业务类型是 20 类,风险等级是 4 类,文档来源是 6 类,那就接三个 head。

class MultiTaskDocClassifier(nn.Module):
    def __init__(self, encoder, hidden_size, task_labels):
        super().__init__()
        self.encoder = encoder
        self.heads = nn.ModuleDict({
            task: nn.Linear(hidden_size, num_labels)
            for task, num_labels in task_labels.items()
        })

    def forward(self, doc_vector):
        return {
            task: head(doc_vector)
            for task, head in self.heads.items()
        }

如果某些维度允许一个文档属于多个标签,就不能用 softmax,而要用 sigmoid + BCEWithLogitsLoss。多维度分类的核心不是把标签硬拼起来,而是把标签体系设计清楚。

6. 如果一个文档有 5000 页,怎么做分类?

答案:

5000 页的文档不能直接丢给任何常规分类模型。这个时候要把分类问题变成一个层级证据聚合问题,先从文档中找出对分类最有用的部分,再基于这些证据做判断。

比较合理的流程是先解析目录、标题、页眉页脚、章节结构,然后按章节或页面分块。每个块先做粗筛,判断它和目标分类维度有没有关系。只保留高相关 chunk,再进行精排、摘要和分类。最后模型不是基于全文判断,而是基于“关键证据片段 + 结构信息 + 摘要”判断。

这种任务里,最重要的是不要平均处理所有页面。5000 页里可能只有几十页真正决定分类,比如摘要、目录、结论、风险提示、技术方案、财务表格说明等。工程上可以设计两阶段模型:第一阶段召回相关片段,第二阶段做文档级分类。

7. 你会怎么给上千页甚至 2GB 的大文档打分?

答案:

大文档打分不能直接让模型读全文后给分,而是要把评分标准拆成若干可验证的评分项。比如合规性、完整性、风险程度、技术可行性、证据充分性,每一项都要对应可检索的证据。

实际做法是先把文档切块并建立索引,然后针对每个评分项生成查询,从文档中召回相关片段。模型只基于这些片段给单项分,并要求输出引用依据。最后再把各项分数按权重汇总成总分。

def final_score(item_scores, weights):
    score = 0
    for item, value in item_scores.items():
        score += value * weights.get(item, 0)
    return round(score, 2)

item_scores = {
    "completeness": 82,
    "risk": 65,
    "feasibility": 78
}

weights = {
    "completeness": 0.4,
    "risk": 0.3,
    "feasibility": 0.3
}

print(final_score(item_scores, weights))

对于 2GB 文件,重点不是模型有多大,而是文档解析、分块索引、证据召回和评分一致性。否则模型给出来的分数很容易变成主观判断,难以复核。

8. 你处理过的文档一般有多大?不同大小的文档方案有什么区别?

答案:

如果是几页到几十页的文档,可以直接按段落切分,召回关键段落后分类。几百页的文档就需要明显的章节结构处理,因为全文 chunk 数量已经比较多,不能全部送入

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

AI-Agent面试实战专栏 文章被收录于专栏

本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.

全部评论

相关推荐

点赞 评论 收藏
分享
3.19申请4.15笔试,200分及格分,240多通过4.23早上专业一面&nbsp;&nbsp;1小时左右自我介绍笔试复盘(自己提前准备,两道编程题错在哪里,为什么会出错自己考完笔试就可以先复盘一下)项目拷打(这方面问的非常细,包括项目的成员构成,整个项目的介绍,对于使用到的技术的了解程度以及假设出现了某个问题应该怎么改进。我的项目距离现在有一段时间了,一些比较细节的东西记不太清楚了,不过运气比较好,面试官提到的大多数问题都是我当时做项目的时候有遇到或者思考过的,所以印象相对深刻)一些AI相关的八股(AIagent)一道手撕题(后来我自己复盘发现我的算法并不完美,但是能够解释测例,也还凑合)4.23下午主管面试&nbsp;&nbsp;30分钟左右自我介绍项目介绍(问的比早上要深,包括使用的技术栈和对其它技术栈有多少了解)对前沿AI发展和AI模型框架的认识其它内容的了解,比赛,居住地,期望入职时间之类的总结:感觉华为比较注重就是实践方面,所以项目经历比较丰富或者对项目的各个方面了解比较深的同学是比较有优势的。笔试方面多刷题应该问题不大,我备考的时候牛客上所有套题基本都刷了两三遍(刷到麻了);面试的话应该就着重项目吧,使用的技术、算法原理什么的要多了解一点然后面试表现得自然一些问题应该不大;八股有,但是基本上点到为止,而且偏机器学习和前沿AI相关的多。主管面我当时是比较紧张,不过主管人很好,整个过程基本上是以一个交流分享的状态进行的。后续是怎么个流程,这样子是能成功入职了还是有其它环节我暂时也不清楚了,但是自己能把握的部分已经全部通过了,剩下的看造化了。希望能对各位求职有帮助。
查看7道真题和解析
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务