Я сталкивался с проблемой построения и использованием скомпилированного модуля Torch CPP в Python. В основном это работает нормально, но у меня были постоянные проблемы с реализацией метода .to () , который отвечает за перемещение параметров модулей и параметров подмодулей в указанное устройство. В моем случае я пытаюсь переместить модель из процессора в CUDA. После составления и импорта .pyd в мой файл тестирования Python, вызов .to () привел к ошибке, в которой говорится, что у моего объекта нет атрибута .to () .
Я посмотрел на собственную реализацию Torch на Github: https://github.com/pytorch/pytorch/blob ... linear.cpp
и попытался идентифицировать тенденции в регистрации параметров и привязки.register_parameter("W_k", W_k_ = torch::zeros({rank_, query_dim_}));
был правильным способом регистрации методов и никогда не видел .to () , чтобы я был запутался в том, если Torch :: nn :: module действительно реализовал метод или если я использовал неправильный класс.#include
#include
#include
#include
#include
class OptimizedACPNImpl : public torch::nn::Module {
private:
int64_t in_features_;
int64_t out_features_;
int64_t rank_;
int64_t query_dim_;
bool has_bias_;
torch::Tensor U_, V_, W_q_, W_k_, bias_, attention_scale_;
// Cache for the key projection
torch::Tensor cached_key_proj_;
bool cache_valid_ = false;
torch::Device last_device_ = torch::Device(torch::kCPU);
// Safety flag for device checking
bool check_device_ = true;
bool first_forward_done_ = false;
public:
OptimizedACPNImpl(int64_t in_features, int64_t out_features,
int64_t rank = -1, int64_t query_dim = 16, bool use_bias = true)
: in_features_(in_features), out_features_(out_features),
query_dim_(query_dim), has_bias_(use_bias) {
if (rank < 0) {
rank_ = static_cast(0.35 * std::min(in_features, out_features));
rank_ = std::max(static_cast(1), rank_);
} else {
rank_ = rank;
}
// Register parameters
register_parameter("U", U_ = torch::zeros({rank_, in_features_}));
register_parameter("V", V_ = torch::zeros({out_features_, rank_}));
register_parameter("W_q", W_q_ = torch::zeros({query_dim_, in_features_}));
register_parameter("W_k", W_k_ = torch::zeros({rank_, query_dim_}));
register_parameter("attention_scale", attention_scale_ = torch::ones(1));
if (has_bias_) {
register_parameter("bias", bias_ = torch::zeros(out_features_));
}
reset_parameters();
}
void reset_parameters() {
double std_val = 0.02;
torch::nn::init::normal_(U_, 0.0, std_val);
torch::nn::init::normal_(V_, 0.0, std_val);
torch::nn::init::normal_(W_q_, 0.0, std_val);
torch::nn::init::normal_(W_k_, 0.0, std_val);
torch::nn::init::constant_(attention_scale_, 0.5);
if (has_bias_) {
torch::nn::init::zeros_(bias_);
}
// Invalidate cache
cache_valid_ = false;
first_forward_done_ = false;
}
// Method to toggle device safety checks
void set_device_checking(bool enabled) {
check_device_ = enabled;
}
// Method to check if device checking is enabled
bool get_device_checking() const {
return check_device_;
}
torch::Tensor compute_key_projection(const torch::Device& device) {
// Check if we can use cached projection (same device and valid)
if (cache_valid_ && (device == last_device_ || !check_device_)) {
return cached_key_proj_;
}
// Move tensors to device if needed
auto W_k_dev = check_device_ ?
(W_k_.device() == device ? W_k_ : W_k_.to(device)) : W_k_;
auto W_q_dev = check_device_ ?
(W_q_.device() == device ? W_q_ : W_q_.to(device)) : W_q_;
// Compute the projection
double scale = 1.0 / std::sqrt(static_cast(query_dim_));
cached_key_proj_ = torch::mm(W_k_dev, W_q_dev) * scale;
cache_valid_ = true;
if (check_device_) {
last_device_ = device;
}
return cached_key_proj_;
}
torch::Tensor forward(const torch::Tensor& x) {
auto device = x.device();
auto x_cont = x.contiguous();
// Check if this is the first forward pass
if (!first_forward_done_) {
// On first forward, ensure all parameters are on the input device
U_ = U_.to(device);
V_ = V_.to(device);
W_q_ = W_q_.to(device);
W_k_ = W_k_.to(device);
attention_scale_ = attention_scale_.to(device);
if (has_bias_) {
bias_ = bias_.to(device);
}
first_forward_done_ = true;
last_device_ = device;
}
// Get device-aware tensors - only perform checks if device checking is enabled
auto U_dev = check_device_ ?
(U_.device() == device ? U_ : U_.to(device)) : U_;
auto V_dev = check_device_ ?
(V_.device() == device ? V_ : V_.to(device)) : V_;
auto attention_scale_dev = check_device_ ?
(attention_scale_.device() == device ? attention_scale_ : attention_scale_.to(device)) :
attention_scale_;
auto bias_dev = has_bias_ ?
(check_device_ ? (bias_.device() == device ? bias_ : bias_.to(device)) : bias_) :
bias_;
// Get key projection (using cache if possible)
auto key_proj = compute_key_projection(device);
// Compute the main pathway and attention in a single batch
auto main = torch::nn::functional::linear(x_cont, U_dev);
auto attn_logits = torch::nn::functional::linear(x_cont, key_proj);
auto attn_weights = torch::softmax(attn_logits, -1);
std::cout
Подробнее здесь: https://stackoverflow.com/questions/795 ... cpp-for-cu
Проблемы с Torch :: nn :: Модуль реализация To (Device) в Torch CPP для CUDA ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Проблемы с Torch :: nn :: Модуль реализация To (Device) в Torch CPP для CUDA
Anonymous » » в форуме Python - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Проблемы с Torch :: nn :: Модуль реализация To (Device) в Torch CPP для CUDA
Anonymous » » в форуме C++ - 0 Ответы
- 11 Просмотры
-
Последнее сообщение Anonymous
-