Skip to content

Conversation

@zeroRains
Copy link
Contributor

@zeroRains zeroRains commented Jul 5, 2025

Support using paddle in safe_open API

This PR allows us to use safe_open API when set the framework='pp' or framework='paddle'. It just like the following code:

from safetensors import safe_open

tensors = {}
with safe_open(filename, framework="paddle") as f:
    for k in f.keys():
        tensors[k] = f.get_tensor(k)

In this PR, I use the latest feature(MmapStorage) in paddle. It only support for paddle >= 3.1.1 or develop version.

We also can use the original way to load tensor if the paddle version is lower than 3.1.1.

ps: MmapStorage have be merged in develop and 3.1.1.

Copy link

@yuanlehome yuanlehome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM,We hope that official classmates can help review and promote code integration. Thanks!

Copy link
Contributor

@Narsil Narsil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good left a few comments.

Comment on lines 278 to 280
"paddle" => Ok(Framework::Paddle),
"paddlepaddle" => Ok(Framework::Paddle),
"pp" => Ok(Framework::Paddle),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove paddlepaddle (I don't see any reference anywhere in the tutorials).

Same for pp unless I missed it as something being regularly used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove paddlepaddle. But we should save pp. pp in paddle just like pt in pytorch and np in numpy.

I also use pp in test case file. Do you mean that the abbreviation is not required?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant, can you point me to places where the abbreviation is used "naturally". Something like tutorials, examples docs from the official paddlepaddle project (or some big user of it).

For numpy (np): https://numpy.org/doc/stable/user/absolute_beginners.html
For pytorch: https://huggingface.co/docs/transformers/main_classes/tokenizer#transformers.PreTrainedTokenizerFast.__call__.return_tensors It's a convention used in a few key places in HF's ecosystem hence why I went with it (despite my preference for having only 1 clear name for things).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it seems no need to save pp, I will remove it later.

let version = Version::from_string(&version).map_err(SafetensorError::new_err)?;

// todo: version check, only paddle 3.1 or develop
if version >= Version::new(3, 1, 0) || version >= Version::new(0, 0, 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove version 0.0.0 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version 0.0.0 means user uses the develop version. The latest develop version have supported this function. Maybe I should use == but not >=.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then yes == is preferred, otherwise afaik users for versions > 0.0.0 < 3.1.0 will encounter issues, right ?

Copy link
Contributor Author

@zeroRains zeroRains Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this feature only support for paddle>=3.1.1 and develop version(0.0.0). It should use the Mmap of safetensors for versions > 0.0.0 < 3.1.1.

Comment on lines 668 to 671
if cur_type == Dtype::U16 {
// paddle set bf16 as u16
cur_type = Dtype::BF16;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

info is the source in the safetensors file, I think this is reversed logic.

Try to use non mutable variables. let cur_type = if info.dtype == xxx{ something } else{ something else};

Make it much easier to be sure no one if modifying this later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will modify it.

@@ -1,7 +1,10 @@
import threading
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this import.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

"a": A,
}
ident = threading.get_ident()
save_file(tensors, f"./tensor_{ident}.safetensors")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use a unique name, no need to use ident.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

enum Device {
Cpu,
Cuda(usize),
Gpu(usize),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's called CUDA, let's not add something new. Let's reuse cuda(usize). If paddle uses a different name, let's just make sure the conversion happen correctly when they are called (so in paddle only code).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I will remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reading this I have question about GPU semantics with paddle, how does it deal with non cuda GPUs ?

Copy link
Contributor Author

@zeroRains zeroRains Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I misunderstood your question. The gpu in paddle refers to the cuda GPU, and other non cuda GPUs are represented by xxx_gpu(like intel_gpu/metax_gpu). This repo will show more ways to access hardware. https://github.com/PaddlePaddle/PaddleCustomDevice

@Narsil

@zeroRains
Copy link
Contributor Author

zeroRains commented Aug 1, 2025

I have modified the code following the comments. Could you review it again? Thanks! @Narsil

@Narsil
Copy link
Contributor

Narsil commented Aug 15, 2025

Since https://github.com/huggingface/safetensors/pull/646/commits is open, maybe we should close this ? It seems the overlap is significant here, right ?

@zeroRains
Copy link
Contributor Author

zeroRains commented Aug 15, 2025

Since https://github.com/huggingface/safetensors/pull/646/commits is open, maybe we should close this ? It seems the overlap is significant here, right ?

No, this PR #646 still has some content that needs to be modified, but the safe_open function is relatively complete. We hope to use the safe_open function as soon as possible, so we hope to merge the current PR first, and then synchronize PR #646 from the main branch. @Narsil

@Narsil
Copy link
Contributor

Narsil commented Aug 15, 2025

Well my comments from here still apply. This PR is breaking paddle <3.1.1

@zeroRains
Copy link
Contributor Author

Well my comments from here still apply. This PR is breaking paddle <3.1.1

OK, I am install the paddlepaddle == 3.0.0. I run the test file test_paddle_comparison.py. I got this error.

image

I should handle the device when I use cuda:x, now it has solved.

Is there any other testing case which will trigger the breaking when paddle < 3.1.1 ?

Copy link
Contributor

@Narsil Narsil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@Narsil
Copy link
Contributor

Narsil commented Aug 18, 2025

We can remove the Storage suffix for both variants to make clippy happy.

@Narsil
Copy link
Contributor

Narsil commented Aug 18, 2025

Actually let me merge it. This is not important.

@Narsil Narsil merged commit a56b49f into huggingface:main Aug 18, 2025
20 of 29 checks passed
@zeroRains zeroRains deleted the pp branch August 18, 2025 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants