Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

float16数据类型支持问题 #1833

Closed
czr-gc opened this issue Aug 4, 2022 · 3 comments
Closed

float16数据类型支持问题 #1833

czr-gc opened this issue Aug 4, 2022 · 3 comments

Comments

@czr-gc
Copy link

czr-gc commented Aug 4, 2022

我们在使用paddle serving并适配自定义硬件类型时,对C++ serving中的float16数据类型有一些问题/疑问:

examples/C++/PaddleClas/imagenet中resnet50 为例

client输入float16数据类型问题:

client端对实际的numpy输入并没有做检查/转数,如果prototxt中定义了输入输出类型为float16,但是实际输入采用了numpy.float32,会出现精度问题。

prototxt定义:

feed_var {
  name: "image"
  alias_name: "image"
  is_lod_tensor: false
  feed_type: 5
  shape: 3
  shape: 224
  shape: 224
}
fetch_var {
  name: "softmax_0.tmp_0"
  alias_name: "score"
  is_lod_tensor: false
  fetch_type: 5
  shape: 1000
}

实际代码调用:

    img = seq(image_file) # img is float32 numpy array here.
    fetch_map = client.predict(
        feed={"image": img}, fetch=["score"], batch=False)

在client.py中,会根据proto定义的float16数据类型,把img转为string数据

string_slot.append(feed_dict[key].tostring())

general_model.cpp中把string数据设置到tensor中,并在之后向server传输。

tensor->set_tensor_content(string_feed[vec_idx]);

但是,img本身为float32数据类型,其内存大小为float16的二倍,不能没有经过转数直接传递到server,否则paddle构建出来的tensor数据错误的:
gdb可以看到输入类型指定为float16时,内存大小却仍然是43224*224=602112

(gdb) p string_feed[vec_idx].size()
$4 = 602112
(gdb) p string_shape[vec_idx]
$5 = std::vector of length 3, capacity 3 = {3, 224, 224}
(gdb) p 3*224*224
$6 = 150528

client float16输出问题:

上述案例中,用户代码对输入做转数操作,则会出现pybind解析错误,client代码示例:

    img = seq(image_file) # img is float32 numpy array here.
    fetch_map = client.predict(
        feed={"image": img.astype(np.float16)}, fetch=["score"], batch=False) # convert img to float16

使用报错:

'utf-8' codec can't decode byte

因为float16的数据是通过string在client/server中传递的,pybind中要求对C++传递到python端的string数据需要能够被utf-8 decode. 除非用户显示指定返回py::bytes不做转换。

因此,以下代码是不是需要改为:return py::bytes(self.get_string_by_name_with_rv(model_idx, name));

return self.get_string_by_name_with_rv(model_idx, name);

pybind参考:https://github.com/pybind/pybind11/blob/master/docs/advanced/cast/strings.rst

另外想问下,我们有可供参考的float16运行案例吗?

@github-actions
Copy link

github-actions bot commented Aug 4, 2022

Message that will be displayed on users' first issue

@HexToString
Copy link
Collaborator

你提的这个问题很好,我们的代码确实存在问题,我会抽空去看一下。谢谢!

@czr-gc
Copy link
Author

czr-gc commented Aug 16, 2022

感谢!

另外,对于async接口,fp16会出现空数据/空指针的情况,原因是以下函数没有处理float16的情况,导致分配的内存为0, 需要增加float16的判断:

    if (dtype == paddle::PaddleDType::FLOAT16) {
      return sizeof(float)/2;
    }

size_t feedvar_element_bytesize(size_t feedvar_index) {

size_t fetchvar_element_bytesize(size_t fetchvar_index) {

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

No branches or pull requests

2 participants