Руководство пользователя Axum для веб-разработки на Rust
Руководство пользователя Axum для веб-разработки на Rust

❝Трудности в жизни не злят, а заставляют спокойнее ❞

Всем привет,Я«Семь, восемь, девять»。один「Сосредоточьтесь на интерфейсеразвиватьтехнология/RustиAIОбмен знаниями о приложениях」изCoder

Предисловие

До,нассуществовать Во многих статьях упоминалосьRust Webрамка。

ЧтосерединаиметьодинRust Webрамкаиз Встречается очень часто -- Это аксум[1].

и в ящике trend[2]из Судя по количеству скачиванийaxumТоже далеко впереди。

так,нассегодняэтот В этой статье будет дано краткое введениеaxumизиспользование。

Ладно, уже поздно, давайте приступим к делу.

Чему мы можем научиться

  1. Необходимые очки знаний
  2. Маршрутизация в Аксуме
  3. существовать Axum Добавить базу данных в
  4. существует Axum Medium из статуса приложения
  5. Средний экстрактор Axum
  6. Axum серединапрерывистый программное обеспечение
  7. существовать Axum Обслуживать статические файлы в
  8. развертывать Axum


1. Необходимые знания

「Необходимые очки знаний」,Просто введение концепции,Никаких углубленных объяснений. потому что,Эти концепции существуют в следующих статьях.,Чтобы письмо было более плавным,такдолжен был иметьсуществовать В текстеиз Сначала поставьте концептуальное объяснение。«Если вы знакомы с этими понятиями, вы можете просто игнорировать их». в то же время,Потому что мою статью читают много людей,так Некоторые очки знаний могут«Я считаю их сокровищами, а вы считаете их не более чем травой и горчицей и выбрасываете их, как изношенную обувь».。Следующие точки знаний,пожалуйста«Использовать по мере необходимости»。 ❞

REST

❝REST[3] is an acronym for REpresentational State Transfer and an architectural style for distributed hypermedia systems. ❞

переведено насередина Вэньцзюда:RESTдаREpresentational State Transferизакроним,такжедаРаспределенная гипермедийная системаизархитектурный стиль。

RESTНетда Что-то вродепротоколилистандартный,ида Что-то вроде«Архитектурный стиль»。Обычно оно основано наHTTPпротокол,использоватьстандартныйизHTTPметод(нравитьсяGETPOSTPUTDELETE)общаться。RESTful API спроектирован так, чтобы быть простым, расширяемым, понятным и совместимым с существующими веб-стандартами.

REST основан на некоторых ограничениях и принципах.,Эти ограниченияипринципы способствуютдизайнсерединаизпростота、Масштабируемостьилицо без гражданства。RESTful Шесть руководящих принципов или ограничений архитектуры:


2. Маршрут в Аксуме

Интересно, использовали ли вы когда-нибудь Express[4] для создания приложений? Если нет, ничего страшного.

Язык кода:javascript
копировать
const express = require("express");
const app = express();

// При отправке на главную страницу GET При запросе используйте "hello front789" в ответ
app.get("/", (req, res) => {
  res.send("hello front789");
});

этотдаперехватыватьExpressОфициальный сайтиз О маршрутизацииизпример。толькоиспользовать Построен всего в несколько строк кодаодинсетевые услуги。

и,нассегодняизглавный геройAxumтакже естьиExpressиз Волшебная функция。Они все следуют за классомRESTfulиз API дизайн。насможет создатьФункция обработчикаhandler)и добавьте их вaxum::Routerначальство。

Язык кода:javascript
копировать
async fn hello_front789() -> &'static str {
  "Передняя часть Цибацзю!"
}

Затемнас Это может быть как нижеэтот样Воля Что添加приезжатьRouterсередина:

Язык кода:javascript
копировать
use axum::{Router, routing::get};

fn init_router() -> Router {
  Router::new()
    .route("/", get(hello_front789))
}

начальстволапшаизпримериExpressдостиг того же самогоиз ЭффектПри отправке на главную страницу GET При запросе используйте "Передняя часть Цибацзю" в ответ

дляФункция обработчикаДавайте поговорим,этонуждатьсядаодинaxum::response::Responseтип,илибыть реализованнымaxum::response::IntoResponse。этотдлябольшинствобазовый тип(Можно обратиться кRust Изучение типов данных[5])

Например, если мы хотим отправить пользователю некоторые JSON данные, которые мы можем использовать Axum из JSON тип, использовать axum::Json типинкапсуляциянасхотетьотправлятьразизданные.

Язык кода:javascript
копировать
use axum::Json;
async fn json() -> Json<Vec<String>> {
    Json(vec!["front".to_owned(), "789".to_owned()])
}

Как будто мы только начали предоставлять коды,настакже МожетвозвращатьсяпрямойвозвращатьсяодинСрез струны(&'static str)。

Мы также можем использовать его напрямую impl IntoResponse。нода,прямойиспользоватьтакжеиметь в видунуждаться「обеспечить всевозвращатьсятип Вседатакой жеизтип」!также就данасможетОбнаружена ненужная ошибка。так,нас Можетдлявозвращатьсятипвыполнитьодин enum или structдостичь«Все возвращаемые типы имеют один и тот же тип»из Ограничения。

Язык кода:javascript
копировать
use axum::{
  response::{
    Response,
    IntoResponse
  },
  Json,
  http::StatusCode
};
use serde::Serialize;

// для упаковки `JSON` Данные тела ответа.
#[derive(Serialize)]
struct Message {
  message: String
}

// Несколько типов `API` из Тип ответа.
// 1. `OK` и `Created` Соответствует разным из `HTTP` код состояния;
// 2. `JsonData` упакованный `Vec<Message>` из `JSON` данные.
enum ApiResponse {
  OK,
  Created,
  JsonData(Vec<Message>),
}

// Это делает `ApiResponse` может быть автоматически преобразован в `axum Response`。
impl IntoResponse for ApiResponse {
  fn into_response(self) -> Response {
   // Проверьте переменную перечисления и верните соответствующий HTTP Код состояния иданные.
    match self {
      Self::OK => (StatusCode::OK).into_response(),
      Self::Created => (StatusCode::CREATED).into_response(),
      Self::JsonData(data) => (StatusCode::OK, Json(data)).into_response()
    }
  }
}

так что проходи ApiResponse перечисление и IntoResponse Реализация, очень удобно генерировать структуру, соответствующую структуре JSON API ответ。и может легкоиз«Совместимость с различными типами кодов состояния ответа»

ЗатемсуществоватьФункция обработчикасерединавыполнить该 enum:

Язык кода:javascript
копировать
async fn my_function() -> ApiResponse {
  ApiResponse::JsonData(vec![Message {
    message: "hello 789".to_owned()
  }])
}

Конечно, мы также можем использовать возвращаемое значение Result[6] Тип! Хотя типы ошибок технически допускают все, что можно преобразовать в HTTP Ответ из содержимого, но мы также можем реализовать тип ошибки для представления HTTP проситьсуществовать Наше приложение может потерпеть неудачу по нескольким причинам, как и в случае с успехом HTTP просить enum Сделай это. Например:

Язык кода:javascript
копировать
enum ApiError {
  BadRequest,
  Forbidden,
  Unauthorised,
  InternalServerError
}

// ... Опустить код ApiResponseиз

async fn my_function() -> Result<ApiResponse, ApiError> {
   //
}

Таким образом, наша маршрутизация может различать ошибки и успехи.


3. Добавьте базу данных в Аксуме.

существоватьRustсерединаиспользоватьбаза данных,Тогда sqlx[7] точно не обойти.

Обычно при настройке базы данных нам может потребоваться настроить соединение с базой данных:

Язык кода:javascript
копировать
use axum::{Router, routing::get};
use sqlx::PgPoolOptions;

#[derive(Clone)]
struct AppState {
  db: PgPool
}

#[tokio::main]
async fn main() {
  let pool = PgPoolOptions::new()
    .max_connections(5)
    .connect(<Адрес базы данных>).await;

  let state = AppState { pool };

  let router = Router::new().route("/", get(hello_world)).with_state(state);

  //... остальная часть кода
}

Нам необходимо обеспечить себя из Postgres[8] экземпляр, независимо от того, установлен ли он локально на локальном компьютере или через Docker Установите тот или иной способ. Однако здесь мы используем Shuttle[9] Это может упростить нашу деятельность.

Язык кода:javascript
копировать
#[shuttle_runtime::main]
async fn axum(
  #[shuttle_shared_db::Postgres] pool: PgPool,
) -> shuttle_axum::ShuttleAxum {
  let state = AppState { pool };

  // .. остальная часть кода
}

4. Статус заявки в Аксуме

существоватьAxumсерединанас Можетиспользоватьaxum::Extension[10]Для обработки хранилища глобальных переменных приложенияизвопрос。нода,это единственныйиз Недостатком являетсядатип небезопасный。существоватьбольшинство Rust Web рамки (включает Axum)середина,насиспользоватьтак называемыйиз«Статус заявки»(app state) - Специальное приложение существует на основе маршрутов, которые совместно используют все переменные структур. существовать Axum Единственное требование для завершения этой операции заключается в том, что структура должна реализовать Clone

Язык кода:javascript
копировать
use sqlx::PgPool; // Это пул соединений Postgres

#[derive(Clone)]
struct AppState {
  pool: PgPool,
}

#[shuttle_runtime::main]
async fn axum(
  #[shuttle_shared_db::Postgres] pool: PgPool,
) -> shuttle_axum::ShuttleAxum {
  let state = AppState { pool };

  // .. остальная часть кода
}

Чтобы использовать его, мы подключаем его к маршрутизатору и передаем состояние в качестве параметра функции-обработчику:

Язык кода:javascript
копировать
use axum::{Router, routing::get, extract::State};

fn init_router() -> Router {
  Router::new()
    .route("/", get(hello_front))
    .route("/do_something", get(do_something))
    .with_state(state)
}

// Обратите внимание, что добавление статуса заявки не является обязательным. - Только тогда, когда существующий захочет его использовать
async fn hello_front() -> &'static str {
  "Hello 789!"
}

async fn do_something(
  State(state): State<AppState>
) -> Result<ApiResponse, ApiError> {
  // .. Наш код
}

Кромеиспользовать#[derive(Clone)]снаружи,Мы также можем использовать Атомный счетчик ссылок(std::sync::Arc)Инкапсуляция структуры состояния приложения。Arcs да Что-то вроде垃圾收集形式,Можно отслеживать количество клонов,И он будет удален только в том случае, если нет копий:

Язык кода:javascript
копировать
use std::sync::Arc;

let state = Arc::new(AppState { db });

Теперь, когда мы добавляем состояние в наше приложение, нам нужно обязательно ссылаться на State Тип экстрактора State<Arc<AppState>>и Нетда State<AppState>

насвозвращаться Может«Извлечение дочернего состояния из состояния приложения»! Это очень полезно, когда нам нужны некоторые переменные из основного состояния, но мы хотим ограничить права управления доступом, к которым может получить доступ данный маршрут. Например:

Язык кода:javascript
копировать
// Статус заявки
#[derive(Clone)]
struct AppState {
  // Сохраните некоторое состояние API
  api_state: ApiState,
}

// конкретный статус API
#[derive(Clone)]
struct ApiState {}

// поддерживает преобразование `AppState` преобразован в `ApiState`
impl FromRef<AppState> for ApiState {
  fn from_ref(app_state: &AppState) -> ApiState {
    app_state.api_state.clone()
  }
}

5. Экстракторы в Аксуме

экстрактор(Extractors)тольконравиться Что名:Они начинаются с HTTP Извлеките содержимое из просить и передайте его в качестве параметров функции-обработчику для работы. В настоящее время имеется встроенная поддержка обычных данных, например получение индивидуальных данных. header、путь、Запрос、форма и JSON

Например, мы можем использовать axum::Json Тип передан из HTTP Извлечено из просить JSON просить тело обработать HTTP просить。

Язык кода:javascript
копировать
use axum::Json;
use serde_json::Value;

async fn my_function(
  Json(json): Json<Value>
) -> Result<ApiResponse, ApiError> {
  // ...Наш код
}

Хотя приведенный выше код может получать данные, поскольку мы используем serde_json::Value,этоизструктураиз Динамичный и изменчивыйиз,может содержать что угодно。(существоватьRust расширяет возможности фронтенд-развивания интерфейсной платформы, которая принадлежит нам.серединанасиспользоватьserde_jsonиметь дело сjsonдокумент)

Чтобы достичь желаемой цели, мы пытаемся использовать реализацию serde::Deserialize из Rust структуратело——этотда Воля«Необходимо преобразовать исходные данные в саму структуру»из:

Язык кода:javascript
копировать
use axum::Json;
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Submission {
  message: String
}

async fn my_function(
  Json(json): Json<Submission>
) -> Result<ApiResponse, ApiError> {
  println!("{}", json.message);

  // ...Наш код
}

форма и URL Параметры запроса также можно обрабатывать таким же образом, добавив соответствующий тип в функцию-обработчик. - Например, экстрактор форм может выглядеть так:

Язык кода:javascript
копировать
async fn my_function(
  Form(form): Form<Submission>
) -> Result<ApiResponse, ApiError> {
  println!("{}", json.message);

  // ...Наш код
}

существоватьотправлять HTTP проситьприезжать API из HTML В конце, конечно, нам также необходимо убедиться, что отправляется правильный тип контента.

headerЭто также можно сделать таким же образомиз Способиметь дело с,ТолькодаheaderНе будет потреблятьсяпроситьтело!нас Можетиспользовать TypedHeader[11] введите, чтобы сделать это. для Axum 0.6,наснуждаться启использоватьheadersФункция,нодасуществовать 0.7 , оно было перенесено в axum-extra[12] ящик, нам нужно добавить typed-header функция, как показано ниже:

Язык кода:javascript
копировать
cargo add axum-extra -F typed-header

использоватьтипизменятьheadersМожет简单地Воля Чтоделатьдля Добавление параметровприезжать Функция обработчикасередина:

Язык кода:javascript
копировать
use headers::ContentType;
use axum::{TypedHeader, headers::Origin}; // существоватьaxum Используется в версии 0.6
use axum_extra::{TypedHeader, headers::Origin}; // существоватьaxum Используется в версии 0.7

async fn my_function(
  TypedHeader(origin): TypedHeader<Origin>
) -> Result<ApiResponse, ApiError> {
  println!("{}", origin.hostname);

  // ...Наш код
}

Кроме TypedHeaders снаружи,axum-extra Есть также много других полезных типов, которые можно использовать. Например, у него есть CookieJar Экстракторы, которые могут помочь управлять cookie


Экстракторы на заказ в Аксуме

Теперь, когда мы знаем больше об экстракторах, возможно, нам будет интересно узнать, как мы можем создавать свои собственные экстракторы. - Например, предположим, что нам нужно создать экстрактор на основе тела просить. Json возвращатьсяда Разобрать форму。позволятьнаснастраиватьнасизструктураи Функция обработчика:

Язык кода:javascript
копировать
#[derive(Debug, Serialize, Deserialize)]
struct Payload {
  foo: String,
}

async fn handler(JsonOrForm(payload): JsonOrForm<Payload>) {
  dbg!(payload);
}

struct JsonOrForm<T>(T);

Сейчас мы можем обеспечить JsonOrForm Реализация структуры FromRequest<S, B>!

Язык кода:javascript
копировать
//выполнить `FromRequest` trait。Это делает `JsonOrForm` может использоваться как `axum extractor` использовать.
#[async_trait]
impl<S, B, T> FromRequest<S, B> for JsonOrForm<T>
where
  B: Send + 'static,
  S: Send + Sync,
  Json<T>: FromRequest<(), B>,
  Form<T>: FromRequest<(), B>,
  T: 'static,
{

  type Rejection = Response;

  async fn from_request(req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
    // Стань первым `content-type` проситьголова。    let content_type_header = req.headers().get(CONTENT_TYPE);
    let content_type = content_type_header.and_then(|value| value.to_str().ok());

    if let Some(content_type) = content_type {
      //  в случае `application/json`, используйте `req.extract()` extractor Извлечено как `Json<T>`。
      if content_type.starts_with("application/json") {
        let Json(payload) = req.extract().await.map_err(IntoResponse::into_response)?;
        return Ok(Self(payload));
      }
      // в случае `application/x-www-form-urlencoded`,Извлечено как `Form<T>`。
      if content_type.starts_with("application/x-www-form-urlencoded") {
        let Form(payload) = req.extract().await.map_err(IntoResponse::into_response)?;
        return Ok(Self(payload));
      }
    }
    // возвращаться `Unsupported Media Type` из Ошибка.
    Err(StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response())
  }

}

Таким образом, этот код позволяет нам гибко с ним обращаться. JSON и Form Форматизпросить Body,делатьдляодинудобныйиз extractor существовать handler используется в.

Это позволяет избежать повторного извлечения парсинга кодов для разных просит. А также унифицировали обработчик подписи.

существовать Axum 0.7 середина,этот略иметь修改。axum::body::Body Больше никакого реэкспорта hyper::body::Body,ида Собственныйизтип - Это означает, что это уже не дженерик, а Request Тип всегда будет использоваться axum::body::Body。этотвеществоначальствоиметь в видунас Тольконуждатьсяудалить B Дженерики:

Язык кода:javascript
копировать
#[async_trait]
impl<S, T> FromRequest<S> for JsonOrForm<T>
where
  S: Send + Sync,
  Json<T>: FromRequest<()>,
  Form<T>: FromRequest<()>,
  T: 'static,
{

  // ...то же, что и выше

}

6. Промежуточное программное обеспечение в Аксуме

как упоминалось ранее,По сравнению с другими фреймворками,Axum Огромным преимуществом существования является то, что оно имеет tower crates Совместимо, что означает, что мы можем Rust API использовать「кто-нибудь хочетиз Tower промежуточное программное обеспечение"!примернравиться,Можем добавить Башню Промежуточное ПО для сжатия ответа:

Язык кода:javascript
копировать
use tower_http::compression::CompressionLayer;
use axum::{routing::get, Router};

fn init_router() -> Router {
  Router::new()
    .route("/", get(hello_world))
    .layer(CompressionLayer::new)
}

Есть много причин Tower промежуточное программное обеспечениекомпозицияиз crate доступно без необходимости писать что-либо самостоятельно программное Если мы существуем, используется в любом приложении! Tower промежуточное программное обеспечение, это хороший способ повторно использовать наше изпромежуточное программное обеспечение,без написания дополнительного кода,Потому что совместимость гарантирует отсутствие проблем.

Мы также можем создать свою собственную, написав Функцияизпромежуточное программное обеспечение. Функция должна быть включена Request и Next типруководить<B>Общая привязка,потому что Axum из body типсуществовать 0.6 in — это общий тип из. Вот пример:

Язык кода:javascript
копировать
use axum::{http::Request, middleware::Next};

async fn check_hello_world<B>(
  req: Request<B>,
  next: Next<B>
) -> Result<Response, StatusCode> {

  // Требуется http crate, чтобы получить имя заголовка
  if req.headers().get(CONTENT_TYPE).unwrap() != "application/json" {
    return Err(StatusCode::BAD_REQUEST);
  }

  Ok(next.run(req).await)
}

существовать Axum 0.7 середина,насвстречаудалить<B>ограничение,потому что Axum из axum::body::Body Тип больше не является универсальным:

Язык кода:javascript
копировать
use axum::{http::Request, middleware::Next};

async fn check_hello_world(
  req: Request,
  next: Next
) -> Result<Response, StatusCode> {

  // ...то же, что и выше

}

Для существования нашего приложения внедрить новое изпромежуточное программное программное обеспечение, мы хотим использовать axum из axum::middleware::from_fn функция,Это позволяет нам использовать функцию в качестве обработчика. существуют на практике,Это выглядит так:

Язык кода:javascript
копировать
use axum::middleware::self;

fn init_router() -> Router {
  Router::new()
    .route("/", get(hello_world))
    .layer(middleware::from_fn(check_hello_world))
}

Если нам нужно добавить состояние приложения в промежуточное программное обеспечение, мы можем добавить его в функцию-обработчик, а затем использовать middleware::from_fn_with_state:

Язык кода:javascript
копировать
fn init_router() -> Router {
  let state = setup_state(); // Инициализировать состояние приложения

  Router::new()
    .route("/", get(hello_world))
    .layer(middleware::from_fn_with_state(state.clone(), check_hello_world))
    .with_state(state)
}

Суммируя,Axum через его Tower изсовместимость,длясуществовать Rust API Используется в мощном изпромежуточном программное обеспечение обеспечивает большое удобство.


7. Обслуживание статических файлов в Аксуме

Предположим, мы хотим существовать Axum Предоставьте несколько статических файлов в —— Или мы использовали что-то вроде React Таким образом, передняя часть JavaScript framework для создания приложения и хотите объединить его с Rust Axum задняя частьобъединены водин Большое приложениеиспользоватьпрограмма,и Нетда Размещайте интерфейс отдельноизадняя часть。

Axum сам по себе не предоставляет эту функциональность, однако имеет; tower-httpтакой жеиз Функция,Последний обеспечивает способ обслуживания наших собственных статических файлов.,несмотря ни на чтонасдабегатьSPA,возвращатьсядаиспользовать Next.js Когда платформа генерирует статические файлы, это просто. HTMLCSS и JavaScriptможно использовать сAxumСлияние。

Если мы Используя статически сгенерированный файл, мы можем легко вставить его в маршрутизатор (при условии, что из статического файла существует корневой каталог проекта dist папка):

Язык кода:javascript
копировать
use tower_http::services::ServeDir;

fn init_router() -> Router {
  Router::new()
    .nest_service("/", ServeDir::new("dist"))
}

Если мы используем ReactVue,может бытьbundleСтроитьприезжать Связанныйдокументпапкасередина,Затем используйте следующее:

Язык кода:javascript
копировать
use tower_http::services::{ServeDir, ServeFile};

fn init_router() -> Router {
  Router::new().nest_service(
    "/", ServeDir::new("dist")
      .not_found_service(ServeFile::new("dist/index.html")),
  )
}

Мы также можем использовать askama[13]、tera[14] и maud[15] (существоватьиспользовать Rust строить React Server Components из Web Сервер[16] Как из легкого JavaScript библиотеки для ускорения производства.


8. Развертывание Аксума

В связи с необходимостью использования Dockerfile,использовать Rust Развертывание серверных программ всегда немного обременительно. нода,Если мы используем Shuttle,Только需использовать cargo shuttle deploy Развертывание завершено. Никакой настройки не требуется.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода