# Donut

Donut 🍩，即文档理解转换器，是一种利用无 OCR 端到端转换器模型进行文档理解的新方法。Donut 不需要现成的 OCR 引擎/API，但它在各种可视化文档理解任务（如可视化文档分类或信息提取（又称文档解析））中表现出了最先进的性能。

## 论文
- [论文地址] [OCR-free Document Understanding Transformer](https://arxiv.org/abs/2111.15664)

## 模型结构

Donut是一种端到端的（即，自包含的）VDU模型，用于通用理解文档图像。Donut的架构非常简单，由基于Transformer的视觉编码器和文本解码器模块组成。请注意，Donut并不依赖于任何与OCR功能相关的模块，而是使用视觉编码器从给定的文档图像中提取特征。接下来的文本解码器将派生的特征映射到一系列子词令牌，以构造所需的结构化格式。每个模型组件都基于Transformer，因此模型可以轻易地以端到端的方式进行训练。

<div align="center">
    <img src="misc/overview.png"/>
</div>

## 算法原理

编码器。视觉编码器将输入文档图像x∈RH×W×C转换为一组嵌入向量{zi|zi∈Rd,1≤i≤n}，其中n是特征图大小或图像块数量，d是编码器的潜在向量的维度。

解码器。给定{z}，文本解码器生成一个令牌序列(yi)mi=1，其中yi∈Rv是第i个令牌的独热向量，v是令牌词汇表的大小，m是超参数。

<div align=center>
    <img src="./misc/model.png"/>
</div>

## 环境配置
### Docker（方法一）
[光源](https://www.sourcefind.cn/#/service-details)拉取docker镜像的地址与使用步骤
```
docker pull image.sourcefind.cn:5000/dcu/admin/base/pytorch:1.13.1-ubuntu20.04-dtk23.10-py38

docker run -it -v /path/your_code_data/:/path/your_code_data/ -v /opt/hyhal/:/opt/hyhal/:ro --shm-size=64G --privileged=true --device=/dev/kfd --device=/dev/dri/ --group-add video --name donut <your imageID> bash

cd /path/your_code_data/

pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
```

### Dockerfile（方法二）
```
cd /path/your_code_data/docker

docker build --no-cache -t donut:latest .

docker run --shm-size=64G --name donut -v /opt/hyhal:/opt/hyhal:ro --privileged=true --device=/dev/kfd --device=/dev/dri/ --group-add video -v /path/your_code_data/:/path/your_code_data/ -it donut bash
```
### Anaconda（方法三）

关于本项目DCU显卡所需的特殊深度学习库可从[光合](https://developer.hpccube.com/tool/)开发者社区下载安装。
```
DTK驱动：dtk23.10
python：python3.8
torch:1.13.0
torchvision:0.14.0
```
`Tips：以上dtk驱动、python、paddle等DCU相关工具版本需要严格一一对应`

```
conda create -n donut python=3.8

conda activate donut

cd /path/your_code_data/

pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple
```

## 数据集

 [naver-clova-ix/cord-v2](https://hf-mirror.com/datasets/naver-clova-ix/cord-v2) 

项目中已提供用于试验训练的迷你数据集，训练数据目录结构如下，用于正常训练的完整数据集请按此目录结构进行制备：
```bash
> tree dataset_name
dataset_name
├── test
│   ├── metadata.jsonl
│   ├── {image_path0}
│   ├── {image_path1}
│             .
│             .
├── train
│   ├── metadata.jsonl
│   ├── {image_path0}
│   ├── {image_path1}
│             .
│             .
└── validation
    ├── metadata.jsonl
    ├── {image_path0}
    ├── {image_path1}
              .
              .

> cat dataset_name/test/metadata.jsonl
{"file_name": {image_path0}, "ground_truth": "{\"gt_parse\": {ground_truth_parse}, ... {other_metadata_not_used} ... }"}
{"file_name": {image_path1}, "ground_truth": "{\"gt_parse\": {ground_truth_parse}, ... {other_metadata_not_used} ... }"}
     .
     .
```
## 训练
### 单机单卡
```
bash single_dcu_train.sh
```


## 推理

### 单机单卡

### 票据OCR

```
python donut_cord_infernce.py
```
### 火车票OCR

```
python donut_zhtrainticket_inference.py
```

## result

### 票据OCR结果

<div align=center>
    <img src="./result/cord1.png"/>
</div>


### 火车票OCR结果

<div align=center>
    <img src="./result/train.png"/>
</div>

### 精度
测试数据： [naver-clova-ix/cord-v2](https://hf-mirror.com/datasets/naver-clova-ix/cord-v2)  ，使用的加速卡:V100S/K100。

| device | train_loss | TED_accuracy_score | F1_accuracy_score |
| :------: | :------: | :------: | :------: |
| V100s | 0.0533 | 0.87157 | 0.796 | 
| K100 | 0.038 | 0.87028 | 0.8047 | 

## 应用场景

### 算法类别
`ocr`

### 热点应用行业
`金融,教育,政府,科研,制造,能源,交通`

## 预训练权重

-  [naver-clova-ix/donut-base](https://huggingface.co/naver-clova-ix/donut-base/tree/official)

-  [donut-base-finetuned-cord-v2](https://huggingface.co/naver-clova-ix/donut-base-finetuned-cord-v2/tree/official)

- [donut-base-finetuned-zhtrainticket](https://huggingface.co/naver-clova-ix/donut-base-finetuned-zhtrainticket/tree/official) 

## 源码仓库及问题反馈
- https://developer.hpccube.com/codes/modelzoo/donut_pytorch
## 参考资料
- [OCR-free Document Understanding Transformer](https://arxiv.org/abs/2111.15664)
- [donut github](https://github.com/clovaai/donut?tab=readme-ov-file)

