大模型输出的数学公式格式化方案

大模型输出数学公式的格式化

最近在做大模型的输出格式化时遇到一个问题,就是数学公式的格式化处理比较差,我是使用的React的react-markdown这个库,它可以通过添加数学的插件数学插件(如 rehype-katex 或 remark-math)来识别数学latex格式的数学公式。

但是在实际的使用过程中,效果并不好,具体来说,他们是基于markdown格式的数学公式来进行渲染,也就是单个$或一对$$美元符号包裹的,但是各家大模型输出的数学公式格式有一定的差别,具体如下图:

deepseek回答

可以看到chatgpt和deepseek的回答会是标准的latex格式\(\)或者\[\] 不能正常渲染,而Claude则是一个markdown格式的数学公,即$或$$。

这样就比较难处理,为了使现代的这种latex能够在react-markdown正常渲染,就需要在渲染前做一些处理,简单来说就是把数学公式加上$符号,当然其中还需做一些处理防止误判。

对于这个问题,可以借鉴一下这个开源代码里的解决方案,具体代码和步骤可以分为:

export function preprocessLaTeX(content: string): string {
  // 步骤一:保护代码块
  const codeBlocks: string[] = [];
  content = content.replace(/(```[\s\S]*?```|`[^`\n]+`)/g, (match, code) => {
    codeBlocks.push(code);
    return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;
  });

  // 步骤二:保护 LaTeX 表达式
  const latexExpressions: string[] = [];
  content = content.replace(/(\$\$[\s\S]*?\$\$|\\\[[\s\S]*?\\\]|\\\(.*?\\\))/g, (match) => {
    latexExpressions.push(match);
    return `<<LATEX_${latexExpressions.length - 1}>>`;
  });

  // 步骤三:将内容中后跟数字的 $(如 $100)转义为 \$,以避免将其误认为是 LaTeX 行内公式的分隔符。
  content = content.replace(/\$(?=\d)/g, '\\$');

  // 步骤四: 将占位符 <<LATEX_n>> 替换回原始的 LaTeX 表达式,确保数学公式内容恢复。
  content = content.replace(/<<LATEX_(\d+)>>/g, (_, index) => latexExpressions[parseInt(index)]);

  // 步骤五: 将占位符 <<CODE_BLOCK_n>> 替换回原始代码块内容。
  content = content.replace(/<<CODE_BLOCK_(\d+)>>/g, (_, index) => codeBlocks[parseInt(index)]);

  // 步骤六:将 \[...\] 和 \(...\) 转换为 $$...$$ 和 $...$
  content = escapeBrackets(content);
  // 对化学公式中的 \ce{} 和 \pu{} 命令添加额外的反斜杠转义(如 $\\ce{} 变为 $\\\\ce{}),以防止解析错误。
  content = escapeMhchem(content);

  return content;
}

替换的函数:

具体来说就是将代码块的,行内的(\(\)),行级的(\[\])都匹配到,然后依次进行处理

export function escapeBrackets(text: string): string {
  const pattern = /(```[\S\s]*?```|`.*?`)|\\\[([\S\s]*?[^\\])\\]|\\\((.*?)\\\)/g;
  return text.replace(
    pattern,
    (
      match: string,
      codeBlock: string | undefined,
      squareBracket: string | undefined,
      roundBracket: string | undefined,
    ): string => {
      if (codeBlock != null) {
        return codeBlock;
      } else if (squareBracket != null) {
        return `$$${squareBracket}$$`;
      } else if (roundBracket != null) {
        return `$${roundBracket}$`;
      }
      return match;
    },
  );
}

// 处理特殊的化学函数
export function escapeMhchem(text: string) {
  return text.replaceAll('$\\ce{', '$\\\\ce{').replaceAll('$\\pu{', '$\\\\pu{');
}

最后在匹配前调用这个预处理:

const Markdown = ({ children }: { children: string }) => {
  const processedContent = preprocessLaTeX(children);

  return (
    <ReactMarkdown 
      remarkPlugins={remarkPlugins} 
      rehypePlugins={[
        [rehypeKatex], 
        [
          rehypeHighlight,
        ]
      ]}
      components={components}
    >
      {processedContent}
    </ReactMarkdown>
  );
};

具体效果如图展示:

### 解决 PP-OCRv4 出现的错误 当遇到 `WARNING: The pretrained params backbone.blocks2.0.dw_conv.lab.scale not in model` 这样的警告时,这通常意味着预训练模型中的某些参数未能匹配到当前配置下的模型结构中[^2]。 对于此问题的一个有效解决方案是采用特定配置文件来适配预训练权重。具体操作方法如下: 通过指定配置文件 `ch_PP-OCRv4_det_student.yml` 并利用已有的最佳精度预训练模型 (`best_accuracy`) 来启动训练过程可以绕过上述不兼容的问题。执行命令如下所示: ```bash python3 tools/train.py -c configs/det/ch_PP-OCRv4/ch_PP-OCRv4_det_student.yml ``` 该方案不仅解决了参数缺失带来的警告,还能够继续基于高质量的预训练成果进行微调,从而提升最终检测效果。 关于蒸馏的概念,在机器学习领域内指的是将大型复杂网络(teacher 模型)的知识迁移到小型简单网络(student 模型)。这里 student 和 teacher 的关系是指两个不同规模或架构的神经网络之间的指导与被指导的关系;其中 teacher 已经经过充分训练并具有良好的性能,而 student 则试图模仿前者的行为模式以达到相似的效果但保持更高效的计算特性。 至于提到的 `Traceback` 错误信息部分,由于未提供具体的跟踪堆栈详情,难以给出针对性建议。不过一般而言,这类报错往往涉及代码逻辑错误或是环境配置不当等问题。为了更好地帮助定位和解决问题,推荐记录完整的异常日志,并仔细检查最近修改过的代码片段以及确认依赖库版本的一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值