- Удалён класс Variable теперь Tensor сам является autograd-узлом.
- Удалён метод .data() - используйте Tensor напрямую и detach() для значений без графа.
- requires_grad задаётся явно через requires_grad_().
- Активации/лоссы переехали в adept::nn::functional.
- Добавлены графовый режим и tracing.
1. Variable → Tensor
Было:
Variable forward(Variable x) { return relu(l1(x)); }
Variable x(batch[0].to(dev), false);
auto loss = cross_entropy_with_logits(net(x), Variable(y.to(dev), false));
auto v = loss.dataat<float3().cpu().2_t>({0,0});
Стало:
using namespace adept::nn::functional;
Tensor forward(Tensor x) { return relu(l1(x)); }
Tensor x = batch[0].to(dev);
auto loss = cross_entropy_with_logits(net(x), y.to(dev));
auto v = loss.detach().cpu().at<float32_t>({0,0});
2. requires_grad и .data()
// было
Variable v(x); v.requires_grad(false);
Tensor raw = v.data();
// стало
Tensor t = x;
t.requires_grad_(); // включить
t.requires_grad_(false); // выключить
Tensor raw = t.detach(); // без узла графа
Обычный Tensor по умолчанию без градиента. Свои параметры помечайте requires_grad_(). Cлои и оптимизаторы делают это сами. Для изменения данных на месте: weight_.copy_from(new_weight).
3. Заголовочные файлы и namespace
// было
#include <adept/autograd/autograd.hpp>
#include <adept/nn/activations.hpp>
#include <adept/nn/cross_entropy.hpp>
using namespace adept;
// стало
#include <adept/graph/autograd.hpp>
#include <adept/nn/functional.hpp>
using namespace adept::nn::functional;
relu, cross_entropy_with_logits, MSE, bce_loss и т.п. больше не лежат в adept::; используйте adept::nn::functional::....
4. Свои операции
Backward-правила теперь capture-free и читают состояние из OpContext:
detail::OpContext ctx("my_op");
ctx.add_input("input", input);
ctx.set_forward([](const std::vector<Tensor>& in, detail::OpContext&) {
return std::vector<Tensor>{my_op_fwd(in[0].detach())};
});
ctx.set_backward([](const Tensor& g, const detail::OpContext& c) {
if (c.input("input").requires_grad())
detail::add_grad(c.input("input"), my_op_bwd(g));
});
return detail::make_op(result, std::move(ctx));
Для нескольких выходов используется detail::make_multi_op.
5.Tracing (трассировка графа)
По умолчанию в Adept используется Eager режим: записывается только gradient tape (операции с `requires_grad`). В новом режиме `Compiled` записываются все операции.
#include <adept/graph/traced_graph.hpp>
auto traced = trace_module(model, [&](const std::vector<Tensor>& in) {
return std::vector<Tensor>{model(in[0])};
}, {example_input}, TraceOptions{.input_names = {"x"}});
Tensor out = traced.forward({runtime_input})[0];
Режим графа: GraphModeGuard(graph_mode_t::Compiled).
Также TraceOptions включают оптимизации: constant folding, CSE, алгебраические упрощения, DCE и анализ fusion-кандидатов.
Ограничения Tracing
- трассировка только для inference: TracedGraph умеет только forward, backprop через него не идёт;
- фиксируется сигнатура входов: количество, shape, dtype и device должны совпадать;
- трассируемая функция выполняется один раз на example inputs, поэтому чтение значений на хосте запрещено;
Ветвления должны зависеть от структуры графа, а не от значений тензоров;
- record_gradients=false по умолчанию — трассированный граф не хранит градиенты.
6. Python
Python API также обновлен в соответствии с изменениями.
#BreakingChanges #API #Tracing #Graph