diff --git a/paddle/phi/kernels/cpu/lu_kernel.cc b/paddle/phi/kernels/cpu/lu_kernel.cc index 9c968a83b111c..b014d9c98845a 100644 --- a/paddle/phi/kernels/cpu/lu_kernel.cc +++ b/paddle/phi/kernels/cpu/lu_kernel.cc @@ -34,6 +34,12 @@ void LUKernel(const Context& dev_ctx, "lu without pivoting is not implemented on the CPU, " "but got pivots=False")); + if (x.numel() == 0) { + dev_ctx.template Alloc(infos); + dev_ctx.template Alloc(pivots); + dev_ctx.template Alloc(out); + return; + } *out = Transpose2DTo6D(dev_ctx, x); auto outdims = out->dims(); diff --git a/paddle/phi/kernels/cpu/weight_quantize_kernel.cc b/paddle/phi/kernels/cpu/weight_quantize_kernel.cc index bb2f840953fe8..dd9a4a763ee87 100644 --- a/paddle/phi/kernels/cpu/weight_quantize_kernel.cc +++ b/paddle/phi/kernels/cpu/weight_quantize_kernel.cc @@ -156,6 +156,14 @@ void WeightQuantizeKernel(const Context& dev_ctx, DenseTensor* out, DenseTensor* scale) { dev_ctx.template Alloc(out); + if (out->numel() == 0) { + if (algo == "llm.int8") { + dev_ctx.template Alloc(scale); + } else { + dev_ctx.template Alloc(scale); + } + return; + } if (algo == "weight_only_int8") { dev_ctx.template Alloc(scale); quant_compute( diff --git a/paddle/phi/kernels/gpu/lu_kernel.cu b/paddle/phi/kernels/gpu/lu_kernel.cu index da5b64b505a25..b04ef2be2e791 100644 --- a/paddle/phi/kernels/gpu/lu_kernel.cu +++ b/paddle/phi/kernels/gpu/lu_kernel.cu @@ -133,6 +133,12 @@ void LUKernel(const Context& dev_ctx, 2, ::common::errors::PreconditionNotMet( "Invalid input x dimensionality: %d (expected ≥2)", x.dims().size())); + if (x.numel() == 0) { + dev_ctx.template Alloc(infos); + dev_ctx.template Alloc(pivots); + dev_ctx.template Alloc(out); + return; + } int64_t largest_matrix = (1LL << 31) - 1; int64_t last = x.dims()[x.dims().size() - 1], second_last = x.dims()[x.dims().size() - 2]; diff --git a/paddle/phi/kernels/gpu/weight_only_linear_grad_kernel.cu b/paddle/phi/kernels/gpu/weight_only_linear_grad_kernel.cu index 300f5d2fc1095..9147ee3f092e9 100644 --- a/paddle/phi/kernels/gpu/weight_only_linear_grad_kernel.cu +++ b/paddle/phi/kernels/gpu/weight_only_linear_grad_kernel.cu @@ -16,6 +16,7 @@ limitations under the License. */ #include "paddle/phi/backends/gpu/gpu_context.h" #include "paddle/phi/common/datatype_traits.h" #include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/kernels/full_kernel.h" #include "paddle/phi/kernels/matmul_kernel.h" #if defined(PADDLE_WITH_CUTLASS) @@ -51,6 +52,11 @@ void WeightOnlyLinearGradKernel(const Context& dev_ctx, int n = weight_scale.dims()[0]; int k = weight.dims()[1]; dev_ctx.template Alloc(x_grad); + if (x_grad->numel() == 0 || out_grad.numel() == 0) { + Full( + dev_ctx, phi::IntArray(common::vectorize(x_grad->dims())), 0, x_grad); + return; + } DenseTensor weight_dequantized; weight_dequantized.Resize({{n, k}}); dev_ctx.template Alloc(&weight_dequantized); diff --git a/paddle/phi/kernels/gpu/weight_only_linear_kernel.cu b/paddle/phi/kernels/gpu/weight_only_linear_kernel.cu index 270b02a5ba449..f46b45a831790 100644 --- a/paddle/phi/kernels/gpu/weight_only_linear_kernel.cu +++ b/paddle/phi/kernels/gpu/weight_only_linear_kernel.cu @@ -16,6 +16,7 @@ limitations under the License. */ #include "paddle/phi/backends/gpu/gpu_context.h" #include "paddle/phi/common/datatype_traits.h" #include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/kernels/full_kernel.h" #include "paddle/phi/kernels/funcs/weight_only_gemv.h" #if defined(PADDLE_WITH_CUTLASS) #include "paddle/phi/kernels/fusion/cutlass/cutlass_kernels/fpA_intB_gemm/fpA_intB_gemm_template.h" @@ -46,6 +47,11 @@ void WeightOnlyLinearKernel(const Context& dev_ctx, #endif dev_ctx.template Alloc(out); + Full( + dev_ctx, phi::IntArray(common::vectorize(out->dims())), 0, out); + if (out->numel() == 0 || x.numel() == 0 || weight.numel() == 0) { + return; + } const T* x_data = x.data(); const int8_t* weight_data = weight.data(); const T* bias_data = bias ? bias.get().data() : nullptr; diff --git a/paddle/phi/kernels/gpu/weight_quantize_kernel.cu b/paddle/phi/kernels/gpu/weight_quantize_kernel.cu index 81f706a9c9441..c3ef20171d6a7 100644 --- a/paddle/phi/kernels/gpu/weight_quantize_kernel.cu +++ b/paddle/phi/kernels/gpu/weight_quantize_kernel.cu @@ -46,6 +46,14 @@ void WeightQuantizeKernel(const Context& dev_ctx, DenseTensor quanted_x; dev_ctx.template Alloc(out); + if (out->numel() == 0) { + if (algo == "llm.int8") { + dev_ctx.template Alloc(scale); + } else { + dev_ctx.template Alloc(scale); + } + return; + } quanted_x.Resize({m, n}); dev_ctx.template Alloc(&quanted_x); std::vector weight_shape{m, n}; diff --git a/paddle/phi/kernels/impl/lu_grad_kernel_impl.h b/paddle/phi/kernels/impl/lu_grad_kernel_impl.h index 71747addfcdbd..3fc553d365a12 100644 --- a/paddle/phi/kernels/impl/lu_grad_kernel_impl.h +++ b/paddle/phi/kernels/impl/lu_grad_kernel_impl.h @@ -31,7 +31,7 @@ void LUGradKernel(const Context& dev_ctx, bool pivot UNUSED, DenseTensor* x_grad) { dev_ctx.template Alloc(x_grad); - + if (x_grad->numel() == 0) return; auto blas = phi::funcs::GetBlas(dev_ctx); auto xdims = x.dims(); diff --git a/paddle/phi/kernels/impl/strided_slice_grad_kernel_impl.h b/paddle/phi/kernels/impl/strided_slice_grad_kernel_impl.h index 3824e301e2ec2..27a4d465eb74b 100644 --- a/paddle/phi/kernels/impl/strided_slice_grad_kernel_impl.h +++ b/paddle/phi/kernels/impl/strided_slice_grad_kernel_impl.h @@ -13,6 +13,7 @@ // limitations under the License. #pragma once +#include "paddle/phi/kernels/full_kernel.h" #include "paddle/phi/kernels/funcs/strided_slice.h" #include "paddle/phi/kernels/strided_slice_grad_kernel.h" diff --git a/paddle/phi/kernels/impl/strided_slice_kernel_impl.h b/paddle/phi/kernels/impl/strided_slice_kernel_impl.h index f8dc298f47e60..87e6c3797e72e 100644 --- a/paddle/phi/kernels/impl/strided_slice_kernel_impl.h +++ b/paddle/phi/kernels/impl/strided_slice_kernel_impl.h @@ -28,6 +28,10 @@ void StridedSliceRawKernel(const Context& dev_ctx, const std::vector& infer_flags, const std::vector& decrease_axis, DenseTensor* out) { + if (out->numel() == 0) { + dev_ctx.template Alloc(out); + return; + } int rank = x.dims().size(); #define SLICE_CASE(Rank) \ case Rank: \ diff --git a/paddle/phi/kernels/stride/strided_slice_grad_kernel.cc b/paddle/phi/kernels/stride/strided_slice_grad_kernel.cc index ee1c2cd2ea236..0b4738509037f 100644 --- a/paddle/phi/kernels/stride/strided_slice_grad_kernel.cc +++ b/paddle/phi/kernels/stride/strided_slice_grad_kernel.cc @@ -44,6 +44,7 @@ void StridedSliceRawGradStridedKernel(const Context& dev_ctx, PD_VISIT_ALL_TYPES(x_grad->dtype(), "StridedSliceRawGradStridedKernel", ([&] { phi::StridedTensorFill(*x_grad, 0, x_grad); })); + if (x_grad->numel() == 0) return; DenseTensor tmp; tmp.set_layout(out_grad.layout()); tmp.set_lod(out_grad.lod()); diff --git a/paddle/phi/kernels/xpu/weight_quantize_kernel.cc b/paddle/phi/kernels/xpu/weight_quantize_kernel.cc index 2e9e779d8aaf4..e8bde6b932a8a 100644 --- a/paddle/phi/kernels/xpu/weight_quantize_kernel.cc +++ b/paddle/phi/kernels/xpu/weight_quantize_kernel.cc @@ -39,6 +39,10 @@ void WeightQuantizeKernel(const Context& dev_ctx, scale->Resize({static_cast(n)}); dev_ctx.template Alloc(scale); + if (out->numel() == 0) { + dev_ctx.template Alloc(out); + return; + } if (algo == "weight_only_int8") { out->Resize({static_cast(k), static_cast(n)}); diff --git a/test/legacy_test/test_lu_op.py b/test/legacy_test/test_lu_op.py index 7f039fad59e90..af338a084d8fa 100644 --- a/test/legacy_test/test_lu_op.py +++ b/test/legacy_test/test_lu_op.py @@ -301,18 +301,37 @@ def run_lu_static(shape, dtype): run_lu_static(tensor_shape, dtype) -class TestLUAPIError(unittest.TestCase): - def test_errors(self): - with paddle.base.dygraph.guard(): - # The size of input in lu should not be 0. - def test_0_size(): - array = np.array([], dtype=np.float32) - x = paddle.to_tensor( - np.reshape(array, [0, 0, 0]), dtype='float32' - ) - paddle.linalg.lu(x, get_infos=True) - - self.assertRaises(ValueError, test_0_size) +# class TestLUAPIError(unittest.TestCase): +# def test_errors(self): +# with paddle.base.dygraph.guard(): +# # The size of input in lu should not be 0. +# def test_0_size(): +# array = np.array([], dtype=np.float32) +# x = paddle.to_tensor( +# np.reshape(array, [0, 0, 0]), dtype='float32' +# ) +# paddle.linalg.lu(x, get_infos=True) + +# self.assertRaises(ValueError, test_0_size) + + +class TestLUAPIZeroSize(unittest.TestCase): + def init_test_case(self): + self.x_shape = [1, 0, 10] + self.dtype = "float32" + + def _test_dygraph(self): + paddle.disable_static() + array = np.ones(self.x_shape).astype(self.dtype) + x = paddle.to_tensor(array, stop_gradient=False) + lu, p, info = paddle.linalg.lu(x, get_infos=True) + loss = lu.sum() + loss.backward() + self.assertEqual(x.grad.shape, x.shape) + + def test_zero_size(self): + self.init_test_case() + self._test_dygraph() if __name__ == "__main__": diff --git a/test/legacy_test/test_strided_slice_op.py b/test/legacy_test/test_strided_slice_op.py index 98e7fee9fc455..1682f7d661414 100644 --- a/test/legacy_test/test_strided_slice_op.py +++ b/test/legacy_test/test_strided_slice_op.py @@ -327,6 +327,17 @@ def test_check_grad(self): pass +# zero size tensor +class TestStrideSliceOp22(TestStrideSliceOp): + def initTestCase(self): + self.input = np.random.rand(10, 0, 100) + self.axes = [1] + self.starts = [-101] + self.ends = [-101] + self.strides = [1] + self.infer_flags = [1] + + class TestStrideSliceOpBool(TestStrideSliceOp): def test_check_grad(self): pass diff --git a/test/quantization/test_weight_only_linear.py b/test/quantization/test_weight_only_linear.py index 164ad49ae7e0f..1c54d0d8bf34c 100644 --- a/test/quantization/test_weight_only_linear.py +++ b/test/quantization/test_weight_only_linear.py @@ -878,6 +878,52 @@ def test_weightonly_linear_backward( quant_x.grad, x.grad, rtol=1e-3, atol=1e-3 ) + def test_weightonly_linear_backward_int4_zerosize(self): + def test_weightonly_linear_backward( + self, algo='weight_only_int4', weight_dtype='int4' + ): + x = ( + paddle.rand(shape=(0, 4096), dtype='float16') + * 1 + / math.sqrt(4096) + ) + x.stop_gradient = False + quant_x = copy.deepcopy(x) + quant_x.stop_gradient = False + weight = ( + paddle.rand(shape=(0, 12288), dtype='float16') + * 1 + / math.sqrt(4096) + ) + + quant_weight, quant_scale = Q.weight_quantize( + x=weight.cuda(), algo=algo + ) + quant_weight = quant_weight.view( + [quant_weight.shape[0] * 2, quant_weight.shape[1] // 2] + ) + dequant_weight = Q.weight_dequantize( + quant_weight.cuda(), quant_scale, algo=algo + ) + np.testing.assert_allclose( + weight, dequant_weight, rtol=1e-2, atol=1e-2 + ) + + quant_out = Q.weight_only_linear( + x=quant_x, + weight=quant_weight, + weight_scale=quant_scale, + weight_dtype=weight_dtype, + ) + out = paddle.matmul(x=x, y=weight) + np.testing.assert_allclose(quant_out, out, rtol=1e-3, atol=1e-3) + + quant_out.backward() + out.backward() + np.testing.assert_allclose( + quant_x.grad, x.grad, rtol=1e-3, atol=1e-3 + ) + if __name__ == '__main__': unittest.main() diff --git a/test/quantization/test_weight_quantize.py b/test/quantization/test_weight_quantize.py index edf14ce60809a..29bc5195abe6f 100644 --- a/test/quantization/test_weight_quantize.py +++ b/test/quantization/test_weight_quantize.py @@ -113,5 +113,22 @@ def run_test(self): baseline = np.array(ref_out).reshape([-1]) np.allclose(baseline, out.astype("int32").numpy(), atol=1e-2) +class WeightQuantizeW4a8ZeroSizeTensorTestCase(unittest.TestCase): + def setUp(self): + self.x_shape = [1, 0, 10] + self.dtype = "float32" + def _test_dygraph(self): + paddle.disable_static() + x = paddle.rand(shape= self.x_shape, dtype=paddle.float16) + x.stop_gradient=False + out, scale = weight_quantize(x, algo='weight_only_int8') + loss = out.sum() + loss.backward() + np.assert_allclose(x.grad.shape,x.shape) + def run_test(self): + self.setUp() + self._test_dygraph() + + if __name__ == '__main__': unittest.main()