Skip to content

Commit d6984d9

Browse files
committed
Merge branch 'main' into fp8
2 parents dcfb44e + 2e5dbc7 commit d6984d9

8 files changed

Lines changed: 505 additions & 14 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ These online demos run entirely in your browser:
5959
- [Segment Anything Model](https://huggingface.co/spaces/radames/candle-segment-anything-wasm): Image segmentation.
6060
- [BLIP](https://huggingface.co/spaces/radames/Candle-BLIP-Image-Captioning): image captioning.
6161

62-
We also provide a some command line based examples using state of the art models:
62+
We also provide some command line based examples using state of the art models:
6363

6464
- [LLaMA v1, v2, and v3](./candle-examples/examples/llama/): general LLM, includes
6565
the SOLAR-10.7B variant.
6666
- [Falcon](./candle-examples/examples/falcon/): general LLM.
67-
- [Codegeex4](./candle-examples/examples/codegeex4-9b/): Code completion,code interpreter,web search,fuction calling,repository-level
67+
- [Codegeex4](./candle-examples/examples/codegeex4-9b/): Code completion, code interpreter, web search, function calling, repository-level
6868
- [GLM4](./candle-examples/examples/glm4/): Open Multilingual Multimodal Chat LMs by THUDM
6969
- [Gemma v1 and v2](./candle-examples/examples/gemma/): 2b and 7b+/9b general LLMs from Google Deepmind.
7070
- [RecurrentGemma](./candle-examples/examples/recurrent-gemma/): 2b and 7b

candle-core/examples/metal_basics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() -> Result<()> {
2121
let x = Tensor::randn(0f32, 1.0, (128, 128), &device)?;
2222
let x1 = x.add(&x)?;
2323
println!("{x1:?}");
24-
// This second synchronize ensures that the command buffer gets commited before the end of the
24+
// This second synchronize ensures that the command buffer gets committed before the end of the
2525
// capture scope.
2626
device.synchronize()?;
2727
Ok(())

candle-core/src/metal_backend/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ impl BackendStorage for MetalStorage {
10551055
)?
10561056
};
10571057
// It is important for the command buffer to be obtained *after* the matmul
1058-
// kernel has run, otherwise we might use a command-buffer that has been commited
1058+
// kernel has run, otherwise we might use a command-buffer that has been committed
10591059
// already resulting in the following error.
10601060
// _status < MTLCommandBufferStatusCommitted >
10611061
// -[IOGPUMetalCommandBuffer setCurrentCommandEncoder:]

candle-onnx/src/eval.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,137 @@ fn simple_eval_(
19501950
);
19511951
}
19521952
}
1953+
"RNN" => {
1954+
// activation_alpha and activation_beta don't apply to (Tanh, Tanh) so ignoring them is okay
1955+
let activations_default = vec!["Tanh".to_string(), "Tanh".to_string()];
1956+
let activations = get_attr_opt_owned::<Vec<String>>(node, "activations")?
1957+
.unwrap_or(activations_default.clone());
1958+
let clip = get_attr_opt::<f32>(node, "clip")?.copied();
1959+
if clip.is_some() {
1960+
bail!("RNN does not currently support clip attribute");
1961+
}
1962+
let direction = get_attr_opt(node, "direction")?.unwrap_or("forward");
1963+
if direction != "forward" {
1964+
bail!("RNN currently only supports direction == \"forward\"");
1965+
}
1966+
let num_directions = if direction == "bidirectional" { 2 } else { 1 };
1967+
let hidden_size: i64 = get_attr(node, "hidden_size").copied()?;
1968+
1969+
// The shape format of inputs X, initial_h and outputs Y, Y_h.
1970+
// If 0, the following shapes are expected:
1971+
// X.shape = [seq_length, batch_size, input_size],
1972+
// Y.shape = [seq_length, num_directions, batch_size, hidden_size],
1973+
// initial_h.shape = Y_h.shape = [num_directions, batch_size, hidden_size].
1974+
// If 1, the following shapes are expected:
1975+
// X.shape = [batch_size, seq_length, input_size],
1976+
// Y.shape = [batch_size, seq_length, num_directions, hidden_size],
1977+
// initial_h.shape = Y_h.shape = [batch_size, num_directions, hidden_size].
1978+
let layout = get_attr_opt(node, "layout")?.copied().unwrap_or(0);
1979+
if layout != 0 {
1980+
bail!("RNN currently only supports layout == 0");
1981+
}
1982+
1983+
// The input sequences packed (and potentially padded) into one 3-D tensor
1984+
// with the shape of `[seq_length, batch_size, input_size]`.
1985+
let x = get(&node.input[0])?;
1986+
// XXX: depends on layout
1987+
let (seq_length, batch_size, _) = x.dims3()?;
1988+
// The weight tensor for the input gate.
1989+
// Concatenation of `Wi` and `WBi` (if bidirectional).
1990+
// The tensor has shape `[num_directions, hidden_size, input_size]`.
1991+
let w = get(&node.input[1])?;
1992+
// The recurrence weight tensor.
1993+
// Concatenation of `Ri` and `RBi` (if bidirectional).
1994+
// This tensor has shape `[num_directions, hidden_size, hidden_size]`.
1995+
let r = get(&node.input[2])?;
1996+
1997+
// The bias tensor for input gate.
1998+
// Concatenation of `[Wbi, Rbi]` and `[WBbi, RBbi]` (if bidirectional).
1999+
// This tensor has shape `[num_directions, 2*hidden_size]`.
2000+
// Optional: If not specified - assumed to be 0.
2001+
let b_default: Tensor;
2002+
let b = match get_opt(3) {
2003+
Some(n) => n?,
2004+
None => {
2005+
b_default = Tensor::zeros(
2006+
(num_directions, 2 * hidden_size as usize),
2007+
DType::F32,
2008+
x.device(),
2009+
)?;
2010+
&b_default
2011+
}
2012+
};
2013+
2014+
// Optional tensor specifying lengths of the sequences in a batch.
2015+
// If not specified - assumed all sequences in the batch to have length `seq_length`.
2016+
// It has shape `[batch_size]`.
2017+
let seq_lens_default: Tensor;
2018+
let seq_lens = match get_opt(4) {
2019+
Some(n) => n?,
2020+
None => {
2021+
seq_lens_default =
2022+
Tensor::full(seq_length as i64, (batch_size,), x.device())?;
2023+
&seq_lens_default
2024+
}
2025+
};
2026+
let seq_lens_is_default =
2027+
(seq_lens.to_vec1::<i64>()?.iter()).all(|e| *e as usize == seq_length);
2028+
if !seq_lens_is_default {
2029+
bail!("RNN currently does not support variable-length sequences. All sequences must use the full sequence length of {}", seq_length);
2030+
}
2031+
2032+
// Optional initial value of the hidden. If not specified - assumed to be 0.
2033+
// It has shape `[num_directions, batch_size, hidden_size]`.
2034+
let initial_h_default: Tensor;
2035+
let initial_h = match get_opt(5) {
2036+
Some(n) => n?,
2037+
_ => {
2038+
initial_h_default = Tensor::zeros(
2039+
(num_directions, batch_size, hidden_size as usize),
2040+
DType::F32,
2041+
x.device(),
2042+
)?;
2043+
&initial_h_default
2044+
}
2045+
};
2046+
2047+
fn choose_activation(activation: &str, x: &Tensor) -> Result<Tensor> {
2048+
match activation {
2049+
"Tanh" => x.tanh(),
2050+
_ => bail!("unsupported activation {activation}"),
2051+
}
2052+
}
2053+
2054+
// these all have [num_directions, ...] shapes
2055+
let w = w.get(0)?;
2056+
let r = r.get(0)?;
2057+
let b = b.get(0)?;
2058+
let idx_wb = Tensor::arange(0, hidden_size, x.device())?;
2059+
let idx_rb = Tensor::arange(hidden_size, 2 * hidden_size, x.device())?;
2060+
let wb = b.index_select(&idx_wb, 0)?;
2061+
let rb = b.index_select(&idx_rb, 0)?;
2062+
let mut h_t = initial_h.get(0)?;
2063+
let mut h_list: Vec<Tensor> = vec![];
2064+
for i in 0..seq_length {
2065+
let xs = x.get(i)?;
2066+
let h = xs
2067+
.matmul(&w.t()?)?
2068+
.add(&h_t.matmul(&r.t()?)?)?
2069+
.add(&wb.unsqueeze(0)?)?
2070+
.add(&rb.unsqueeze(0)?)?;
2071+
let h = choose_activation(&activations[0], &h)?;
2072+
h_list.push(h.to_owned());
2073+
h_t = h;
2074+
}
2075+
let h = Tensor::stack(&h_list, 0)?;
2076+
let h =
2077+
h.reshape((seq_length, num_directions, batch_size, hidden_size as usize))?;
2078+
values.insert(node.output[0].clone(), h);
2079+
values.insert(
2080+
node.output[1].clone(),
2081+
h_t.reshape((num_directions, batch_size, hidden_size as usize))?,
2082+
);
2083+
}
19532084
// https://onnx.ai/onnx/operators/onnx__Xor.html
19542085
"Xor" => {
19552086
// Since we don't have a `DType::Bool` yet, this ensures that we are working with `0`(False) & `1`(True)
@@ -1966,6 +2097,11 @@ fn simple_eval_(
19662097
let output = input.sign()?;
19672098
values.insert(node.output[0].clone(), output);
19682099
}
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?);
19692105
"Resize" => {
19702106
let input = get(&node.input[0])?;
19712107

@@ -2234,6 +2370,7 @@ fn simple_eval_(
22342370
values.insert(node.output[0].clone(), output);
22352371
}
22362372
op_type => bail!("unsupported op_type {op_type} for op {node:?}"),
2373+
22372374
}
22382375
}
22392376
graph

0 commit comments

Comments
 (0)