Skip to content

Commit 2e5dbc7

Browse files
authored
candle-onnx: Implement Hard Swish operator (huggingface#2980)
* feat: added Elu operator * feat: added hard swish * added more tests for hard swish * clened up --------- authored-by: misadowsk <michalsad.protondynamic@gmail.com>
1 parent 23968db commit 2e5dbc7

2 files changed

Lines changed: 92 additions & 1 deletion

File tree

candle-onnx/src/eval.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,11 @@ fn simple_eval_(
20972097
let output = input.sign()?;
20982098
values.insert(node.output[0].clone(), output);
20992099
}
2100+
"HardSwish" => {
2101+
let input = get(&node.input[0])?;
2102+
let hard_sigmoid = candle_nn::ops::hard_sigmoid(&input)?;
2103+
let output = input * hard_sigmoid;
2104+
values.insert(node.output[0].clone(), output?);
21002105
"Resize" => {
21012106
let input = get(&node.input[0])?;
21022107

@@ -2365,6 +2370,7 @@ fn simple_eval_(
23652370
values.insert(node.output[0].clone(), output);
23662371
}
23672372
op_type => bail!("unsupported op_type {op_type} for op {node:?}"),
2373+
23682374
}
23692375
}
23702376
graph

candle-onnx/tests/ops.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6247,6 +6247,92 @@ fn test_sign_operation() -> Result<()> {
62476247
Ok(())
62486248
}
62496249

6250+
#[test]
6251+
fn test_hard_swish() -> candle::Result<()> {
6252+
{
6253+
let manual_graph = create_model_proto_with_graph(Some(GraphProto {
6254+
node: vec![NodeProto {
6255+
op_type: "HardSwish".to_string(),
6256+
input: vec![INPUT_X.to_string()],
6257+
output: vec![OUTPUT_Z.to_string()],
6258+
..Default::default()
6259+
}],
6260+
input: vec![ValueInfoProto {
6261+
name: INPUT_X.to_string(),
6262+
..Default::default()
6263+
}],
6264+
output: vec![ValueInfoProto {
6265+
name: OUTPUT_Z.to_string(),
6266+
..Default::default()
6267+
}],
6268+
..Default::default()
6269+
}));
6270+
let input_data = vec![-4.0f32, -3.0, 0.0, 2.0, 3.0, 5.0];
6271+
let input_tensor = Tensor::from_vec(input_data.clone(), (input_data.len(),), &Device::Cpu)?;
6272+
let mut inputs = HashMap::new();
6273+
inputs.insert(INPUT_X.to_string(), input_tensor);
6274+
6275+
let outputs = simple_eval(&manual_graph, inputs)?;
6276+
let output = outputs.get(OUTPUT_Z).expect("missing output Z");
6277+
let output_vec = output.to_vec1::<f32>()?;
6278+
6279+
let expected = vec![
6280+
0.0,
6281+
0.0,
6282+
0.0,
6283+
1.6666666,
6284+
3.0,
6285+
5.0,
6286+
];
6287+
6288+
for (i, (got, exp)) in output_vec.iter().zip(expected.iter()).enumerate() {
6289+
let diff = (got - exp).abs();
6290+
assert!(
6291+
diff < 1e-4,
6292+
"Mismatch at index {i}: got {got}, expected {exp}, diff={diff}"
6293+
);
6294+
}
6295+
}
6296+
{
6297+
let manual_graph = create_model_proto_with_graph(Some(GraphProto {
6298+
node: vec![NodeProto {
6299+
op_type: "HardSwish".to_string(),
6300+
input: vec![INPUT_X.to_string()],
6301+
output: vec![OUTPUT_Z.to_string()],
6302+
..Default::default()
6303+
}],
6304+
input: vec![ValueInfoProto {
6305+
name: INPUT_X.to_string(),
6306+
..Default::default()
6307+
}],
6308+
output: vec![ValueInfoProto {
6309+
name: OUTPUT_Z.to_string(),
6310+
..Default::default()
6311+
}],
6312+
..Default::default()
6313+
}));
6314+
let input_data = vec![-4.0f32, -2.0, 0.0, 2.0, 4.0];
6315+
let input_tensor = Tensor::from_vec(input_data.clone(), (input_data.len(),), &Device::Cpu)?;
6316+
let mut inputs = HashMap::new();
6317+
inputs.insert(INPUT_X.to_string(), input_tensor);
6318+
6319+
let outputs = simple_eval(&manual_graph, inputs)?;
6320+
let output = outputs.get(OUTPUT_Z).expect("missing output Z");
6321+
let output_vec = output.to_vec1::<f32>()?;
6322+
6323+
let expected = vec![0.0, -0.33333334, 0.0, 1.6666667, 4.0 ];
6324+
6325+
for (i, (got, exp)) in output_vec.iter().zip(expected.iter()).enumerate() {
6326+
let diff = (got - exp).abs();
6327+
assert!(
6328+
diff < 1e-4,
6329+
"Mismatch at index {i}: got {got}, expected {exp}, diff={diff}"
6330+
);
6331+
}
6332+
}
6333+
Ok(())
6334+
}
6335+
62506336
#[test]
62516337
fn test_scatternd_operation() -> Result<()> {
62526338
// Example 1 based on ONNX documentation
@@ -6752,6 +6838,5 @@ fn test_trilu_operation() -> Result<()> {
67526838
]
67536839
);
67546840
}
6755-
67566841
Ok(())
67576842
}

0 commit comments

Comments
 (0)