# Tải dữ liệu pdf

> [!WARNING]
> Hỗ trợ Pdf là thử nghiệm và có thể thay đổi.

Bộ dữ liệu Pdf có các cột kiểu [Pdf](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Pdf), chứa các đối tượng `pdfplumber`.

> [!TIP]
> Để làm việc với các bộ dữ liệu pdf, bạn cần cài đặt gói `pdfplumber`. Xem hướng dẫn [cài đặt](https://github.com/jsvine/pdfplumber#installation) để biết cách cài đặt.

Khi bạn tải một tập dữ liệu pdf và gọi cột pdf, các tệp pdf sẽ được giải mã thành các Pdf của `pdfplumber`:

```py
>>> from datasets import load_dataset, Pdf

>>> dataset = load_dataset("path/to/pdf/folder", split="train")
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1075bc320>
```

> [!WARNING]
> Truy cập vào tập dữ liệu pdf bằng cách sử dụng chỉ số hàng trước, sau đó là cột `pdf` - `dataset[0]["pdf"]` - để tránh tạo tất cả các đối tượng pdf trong tập dữ liệu. Nếu không, đây có thể là một quá trình chậm và tốn thời gian nếu bạn có một tập dữ liệu lớn.

Để tìm hiểu cách tải bất kỳ loại tập dữ liệu nào, hãy xem hướng dẫn tải chung.

## Đọc các trang

Truy cập các trang trực tiếp từ tệp pdf bằng thuộc tính `.pages`.

Sau đó, bạn có thể sử dụng các hàm của `pdfplumber` để đọc văn bản, bảng và hình ảnh, ví dụ:

```python
>>> pdf = dataset[0]["pdf"]
>>> first_page = pdf.pages[0]
>>> first_page
<Page:1>
>>> first_page.extract_text()
Docling Technical Report
Version1.0
ChristophAuer MaksymLysak AhmedNassar MicheleDolfi NikolaosLivathinos
PanosVagenas CesarBerrospiRamis MatteoOmenetti FabianLindlbauer
KasperDinkla LokeshMishra YusikKim ShubhamGupta RafaelTeixeiradeLima
ValeryWeber LucasMorin IngmarMeijer ViktorKuropiatnyk PeterW.J.Staar
AI4KGroup,IBMResearch
Ru¨schlikon,Switzerland
Abstract
This technical report introduces Docling, an easy to use, self-contained, MIT-
licensed open-source package for PDF document conversion.
...
>>> first_page.images
In [24]: first_page.images
Out[24]: 
[{'x0': 256.5,
  'y0': 621.0,
  'x1': 355.49519999999995,
  'y1': 719.9952,
  'width': 98.99519999999995,
  'height': 98.99519999999995,
  'name': 'Im1',
  'stream': <PDFStream(44): raw=88980, {'Type': /'XObject', 'Subtype': /'Image', 'BitsPerComponent': 8, 'ColorSpace': /'DeviceRGB', 'Filter': /'DCTDecode', 'Height': 1024, 'Length': 88980, 'Width': 1024}>,
  'srcsize': (1024, 1024),
  'imagemask': None,
  'bits': 8,
  'colorspace': [/'DeviceRGB'],
  'mcid': None,
  'tag': None,
  'object_type': 'image',
  'page_number': 1,
  'top': 72.00480000000005,
  'bottom': 171.0,
  'doctop': 72.00480000000005}]
>>> first_page.extract_tables()
[]
```

Bạn cũng có thể tải mỗi trang dưới dạng `PIL.Image`:

```python
>>> import PIL.Image
>>> import io
>>> first_page.to_image()
<pdfplumber.display.PageImage at 0x107d68dd0>
>>> buffer = io.BytesIO()
>>> first_page.to_image().save(buffer)
>>> img = PIL.Image.open(buffer)
>>> img
<PIL.PngImagePlugin.PngImageFile image mode=P size=612x792>
```

Lưu ý rằng bạn có thể truyền `resolution=` vào `.to_image()` để hiển thị hình ảnh ở độ phân giải cao hơn mặc định (72 ppi).

## Tệp cục bộ

Bạn có thể tải một tập dữ liệu từ đường dẫn pdf. Sử dụng hàm [cast_column()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Dataset.cast_column) để nhận một cột chứa các đường dẫn tệp pdf, và giải mã nó thành pdf `pdfplumber` với tính năng [Pdf](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Pdf):
```py
>>> from datasets import Dataset, Pdf

>>> dataset = Dataset.from_dict({"pdf": ["path/to/pdf_1", "path/to/pdf_2", ..., "path/to/pdf_n"]}).cast_column("pdf", Pdf())
>>> dataset[0]["pdf"]
<pdfplumber.pdf.PDF at 0x1657d0280>
```

Nếu bạn chỉ muốn tải đường dẫn gốc của bộ dữ liệu pdf mà không giải mã đối tượng pdf, hãy đặt `decode=False` trong tính năng [Pdf](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.Pdf):

```py
>>> dataset = dataset.cast_column("pdf", Pdf(decode=False))
>>> dataset[0]["pdf"]
{'bytes': None,
 'path': 'path/to/pdf/folder/pdf0.pdf'}
```

## PdfFolder

Bạn cũng có thể tải một dataset bằng trình xây dựng dataset `PdfFolder`, không yêu cầu viết dataloader tùy chỉnh. Điều này khiến `PdfFolder` trở nên lý tưởng để nhanh chóng tạo và tải các dataset pdf gồm vài nghìn tệp pdf cho các tác vụ thị giác khác nhau. Cấu trúc dataset pdf của bạn nên trông như sau:

```
folder/train/resume/0001.pdf
folder/train/resume/0002.pdf
folder/train/resume/0003.pdf

folder/train/invoice/0001.pdf
folder/train/invoice/0002.pdf
folder/train/invoice/0003.pdf
```

Nếu bộ dữ liệu tuân theo cấu trúc `PdfFolder`, bạn có thể tải nó trực tiếp bằng [load_dataset()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_dataset):

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_name")
>>> # OR locally:
>>> dataset = load_dataset("/path/to/folder")
```

Đối với các bộ dữ liệu cục bộ, điều này tương đương với việc truyền `pdffolder` thủ công trong [load_dataset()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_dataset) và thư mục trong `data_dir`:

```py
>>> dataset = load_dataset("pdffolder", data_dir="/path/to/folder")
```

Sau đó, bạn có thể truy cập các tệp pdf dưới dạng các đối tượng `pdfplumber.pdf.PDF`:

```
>>> dataset["train"][0]
{"pdf": <pdfplumber.pdf.PDF at 0x161715e50>, "label": 0}

>>> dataset["train"][-1]
{"pdf": <pdfplumber.pdf.PDF at 0x16170bd90>, "label": 1}
```

Để bỏ qua thông tin trong tệp metadata, đặt `drop_metadata=True` trong [load_dataset()](/docs/datasets/v5.2.0/vi/package_reference/loading_methods#datasets.load_dataset):

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_with_metadata", drop_metadata=True)
```

Nếu bạn không có tệp metadata, `PdfFolder` sẽ tự động suy ra tên nhãn từ tên thư mục. Nếu bạn muốn loại bỏ các nhãn được tạo tự động, hãy đặt `drop_labels=True`. Trong trường hợp này, tập dữ liệu của bạn sẽ chỉ chứa một cột pdf:

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("username/dataset_without_metadata", drop_labels=True)
```

Cuối cùng, đối số `filters` cho phép bạn chỉ tải một tập con của bộ dữ liệu, dựa trên điều kiện về nhãn hoặc metadata. Điều này đặc biệt hữu ích nếu metadata ở định dạng Parquet, vì định dạng này cho phép lọc nhanh. Cũng nên sử dụng đối số này cùng với `streaming=True`, vì mặc định bộ dữ liệu sẽ được tải xuống hoàn toàn trước khi lọc.

```python
>>> filters = [("label", "=", 0)]
>>> dataset = load_dataset("username/dataset_name", streaming=True, filters=filters)
```

> [!TIP]
> Để biết thêm thông tin về việc tạo bộ dữ liệu `PdfFolder` của riêng bạn, hãy xem hướng dẫn [Tạo bộ dữ liệu pdf](./document_dataset).

## Giải mã Pdf

Mặc định, các tệp pdf được giải mã tuần tự dưới dạng `PDFs` của pdfplumber khi bạn lặp qua một dataset. Quá trình này giải mã tuần tự metadata của các tệp pdf và không đọc các trang pdf cho đến khi bạn truy cập chúng.

Tuy nhiên, có thể tăng tốc bộ dữ liệu đáng kể bằng cách giải mã đa luồng:

```python
>>> import os
>>> num_threads = num_threads = min(32, (os.cpu_count() or 1) + 4)
>>> dataset = dataset.decode(num_threads=num_threads)
>>> for example in dataset:  # up to 20 times faster !
...     ...
```

Bạn có thể bật đa luồng bằng cách sử dụng `num_threads`. Điều này đặc biệt hữu ích để tăng tốc độ truyền dữ liệu từ xa. Tuy nhiên, nó có thể chậm hơn so với `num_threads=0` đối với dữ liệu cục bộ trên các ổ đĩa nhanh.

Nếu bạn không quan tâm đến các tài liệu được giải mã dưới dạng `PDFs` của pdfplumber và muốn truy cập đường dẫn/bytes thay vào đó, bạn có thể tắt giải mã:

```python
>>> dataset = dataset.decode(False)
```

Lưu ý: [IterableDataset.decode()](/docs/datasets/v5.2.0/vi/package_reference/main_classes#datasets.IterableDataset.decode) hiện chỉ khả dụng cho các bộ dữ liệu dạng streaming.

