Розробка системи токенізації AI-моделей

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи токенізації AI-моделей
Складний
~1-2 тижні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1122
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    859

Розроблення системи токенізації AI-моделей

Токенізація AI-моделей — це не просто «обернути модель в NFT». Це повнофункціональна економічна інфраструктура: права на використання, моделі доходу для творців, перевірка виходу on-chain та механізми управління версіями моделей. Завдання складне, тому що AI-модель — це не статичний актив, як зображення, а живий артефакт із ваговими параметрами, версіями, форками fine-tune та витратами на обчислювальний висновок.

Ринок рухається в бік децентралізованих AI-маркетплейсів: Bittensor, Ritual, Gensyn, Hyperbolic — різні підходи до однієї проблеми. Але більшість команд будує токенізацію поверх них або самостійно, під конкретну вертикаль (медицина, фінанси, генерація контенту).

Архітектура: що саме ми токенізуємо

Перед написанням смарт-контрактів потрібно відповісти на питання: що є токенізованим активом?

Варіанти:

  • Ваги моделей — самі параметри (checkpoint), зберігаються off-chain (IPFS, Arweave, Filecoin), on-chain — хеш та метаданні
  • Права на висновок — доступ до API обчислень, не до ваг
  • Права на fine-tune — можливість створити похідну модель від базової
  • Доля в доходах моделі — токен розподілу доходу, який не дає прямого доступу до ваг

У більшості виробничих випадків токенізуються саме права на висновок плюс опціонально розподіл доходів. Ваги публічно доступні рідко (це IP творця).

Зберігання ваг та перевірка цілісності

contract AIModelRegistry {
    struct ModelVersion {
        bytes32 weightsHash;        // SHA-256 хеш файлу контрольної точки
        string storageURI;          // ipfs://... або ar://...
        uint256 parameterCount;     // кількість параметрів (для ціноутворення)
        string architecture;        // "llama-3-8b", "stable-diffusion-xl"
        uint256 registeredAt;
        address creator;
        bool active;
    }
    
    struct InferenceToken {
        uint256 modelId;
        uint256 versionId;
        uint256 callsRemaining;     // обмеження викликів
        uint256 expiresAt;          // часове обмеження
        bool transferable;
        address holder;
    }
    
    mapping(uint256 => ModelVersion[]) public modelVersions;
    mapping(uint256 => InferenceToken) public inferenceTokens;
    
    uint256 private _modelCounter;
    uint256 private _tokenCounter;
    
    event ModelRegistered(uint256 indexed modelId, address creator, bytes32 weightsHash);
    event InferenceTokenMinted(uint256 indexed tokenId, uint256 modelId, address holder);
    
    function registerModel(
        bytes32 weightsHash,
        string calldata storageURI,
        uint256 parameterCount,
        string calldata architecture
    ) external returns (uint256 modelId) {
        modelId = ++_modelCounter;
        modelVersions[modelId].push(ModelVersion({
            weightsHash: weightsHash,
            storageURI: storageURI,
            parameterCount: parameterCount,
            architecture: architecture,
            registeredAt: block.timestamp,
            creator: msg.sender,
            active: true
        }));
        emit ModelRegistered(modelId, msg.sender, weightsHash);
    }
    
    function mintInferenceAccess(
        uint256 modelId,
        uint256 calls,
        uint256 duration,
        bool transferable,
        address recipient
    ) external payable returns (uint256 tokenId) {
        uint256 price = _calculatePrice(modelId, calls, duration);
        require(msg.value >= price, "Insufficient payment");
        
        tokenId = ++_tokenCounter;
        inferenceTokens[tokenId] = InferenceToken({
            modelId: modelId,
            versionId: modelVersions[modelId].length - 1,
            callsRemaining: calls,
            expiresAt: block.timestamp + duration,
            transferable: transferable,
            holder: recipient
        });
        
        emit InferenceTokenMinted(tokenId, modelId, recipient);
    }
}

Перевірка висновків моделей on-chain: zkML

Найскладніша частина системи — довести, що конкретний вихід дійсно отриманий від конкретної моделі з конкретними вагами без перерахунку висновку on-chain (неможливо при будь-якому розумному розмірі моделі).

Рішення — zkML (zero-knowledge machine learning). Генерується ZK-доказ того, що обчислення виконано правильно, доказ перевіряється on-chain.

Стек zkML

Фреймворк Підхід Обмеження Зрілість
ezkl PLONK circuit із ONNX Моделі до ~100M параметрів Production
RISC Zero zkVM, будь-який Rust код Висока вартість доказу Production
Modulus Labs Користувацькі circuit Потрібна партнерство Beta
Giza Starknet-орієнтований Обмежена екосистема Alpha

ezkl — найпрактичніший вибір для більшості завдань:

import ezkl
import torch
import json

# Експортувати модель у ONNX
model = YourModel()
model.eval()
dummy_input = torch.randn(1, 128)
torch.onnx.export(model, dummy_input, "model.onnx", opset_version=11)

# Налаштування ezkl
settings = ezkl.PyRunArgs()
settings.input_visibility = "public"
settings.output_visibility = "public"
settings.param_visibility = "fixed"  # ваги фіксовані в circuit

await ezkl.gen_settings("model.onnx", "settings.json", py_run_args=settings)
await ezkl.calibrate_settings("input.json", "model.onnx", "settings.json", "resources")

# Компілювання circuit
await ezkl.compile_circuit("model.onnx", "circuit.compiled", "settings.json")

# Генерування ключів
await ezkl.setup("circuit.compiled", "vk.key", "pk.key")

# Генерування свідка та доказу
await ezkl.gen_witness("input.json", "circuit.compiled", "witness.json")
await ezkl.prove("witness.json", "circuit.compiled", "pk.key", "proof.json")

# Перевірка (те ж саме на-chain)
result = await ezkl.verify("proof.json", "settings.json", "vk.key")
print(f"Proof valid: {result}")

Для перевірки on-chain ezkl генерує верифікатор Solidity:

ezkl create-evm-verifier \
    --vk-path vk.key \
    --settings-path settings.json \
    --sol-code-path verifier.sol \
    --abi-path verifier.abi

Генерований verifier.sol розгортається як окремий контракт. Основний реєстр викликає його під час кожного доказу висновку on-chain.

Управління версіями та форки моделей

AI-моделі живуть та еволюціонують. Вам потрібен механізм on-chain для керування версіями та похідними моделями (fine-tunes).

Граф деривативів

contract ModelDerivativeGraph {
    struct DerivativeRelation {
        uint256 parentModelId;
        uint256 parentVersionId;
        uint256 royaltyBps;         // базисні пункти роялті для батьківської моделі
        bool requiresApproval;      // потрібне схвалення від творця базової моделі
        bool approved;
    }
    
    // childModelId => relation
    mapping(uint256 => DerivativeRelation) public derivatives;
    
    // Реєстр роялті: при кожному висновку похідної моделі,
    // % йде на адресу творця базової моделі
    function registerFineTune(
        uint256 childModelId,
        uint256 parentModelId,
        uint256 parentVersionId,
        uint256 royaltyBps
    ) external {
        ModelVersion memory parent = registry.getVersion(parentModelId, parentVersionId);
        
        // Якщо базова модель потребує схвалення — встановити прапор
        bool needsApproval = parentModelConfig[parentModelId].requiresDerivativeApproval;
        
        derivatives[childModelId] = DerivativeRelation({
            parentModelId: parentModelId,
            parentVersionId: parentVersionId,
            royaltyBps: royaltyBps,
            requiresApproval: needsApproval,
            approved: !needsApproval
        });
        
        if (!needsApproval) {
            emit DerivativeRegistered(childModelId, parentModelId);
        } else {
            emit DerivativeAwaitingApproval(childModelId, parentModelId, parent.creator);
        }
    }
    
    function distributeInferenceRevenue(uint256 modelId, uint256 amount) internal {
        // Підняти по дереву деривативів та розподілити роялті
        uint256 currentModel = modelId;
        uint256 remaining = amount;
        
        while (derivatives[currentModel].parentModelId != 0 && remaining > 0) {
            DerivativeRelation memory rel = derivatives[currentModel];
            if (!rel.approved) break;
            
            uint256 royalty = remaining * rel.royaltyBps / 10000;
            address parentCreator = registry.getCreator(rel.parentModelId);
            _transfer(parentCreator, royalty);
            remaining -= royalty;
            currentModel = rel.parentModelId;
        }
        
        // Залишок — творцю листяної моделі
        _transfer(registry.getCreator(modelId), remaining);
    }
}

Ціноутворення висновків

Вартість виклику моделі залежить від кількох параметрів. Простої лінійної залежності працює погано — різні запити до однієї моделі можуть відрізнятися по витратах обчислень на порядок (довжина контексту для LLM, дозвіл для дифузійних моделей).

Динамічне ціноутворення

contract InferencePricing {
    struct PricingConfig {
        uint256 basePricePerCall;       // базова ціна за виклик
        uint256 pricePerInputToken;     // для LLM: ціна за input токен
        uint256 pricePerOutputToken;    // для LLM: ціна за output токен
        uint256 pricePerMegapixel;      // для моделей зображень
        uint256 currency;               // 0=native, 1=USDC, 2=USDT
        uint256 creatorShareBps;        // доля творця від доходу
        uint256 platformShareBps;       // доля платформи
    }
    
    mapping(uint256 => PricingConfig) public modelPricing;
    
    function estimateCallCost(
        uint256 modelId,
        uint256 inputTokens,
        uint256 expectedOutputTokens,
        uint256 imageWidth,
        uint256 imageHeight
    ) external view returns (uint256 totalCost) {
        PricingConfig memory config = modelPricing[modelId];
        
        totalCost = config.basePricePerCall;
        totalCost += inputTokens * config.pricePerInputToken;
        totalCost += expectedOutputTokens * config.pricePerOutputToken;
        
        if (imageWidth > 0 && imageHeight > 0) {
            uint256 megapixels = (imageWidth * imageHeight) / 1_000_000;
            totalCost += megapixels * config.pricePerMegapixel;
        }
    }
}

Токен-гейтинг та доступ до моделей

Крім моделей pay-per-call, система підтримує token-gating: власники конкретного ERC-20 або ERC-721 токена отримують доступ до моделі без додаткової оплати (або зі скидкою).

Це відкриває сценарії: модель як частина NFT-колекції (кожен власник NFT отримує доступ до AI-асистента), стейкинг-базований доступ (застейкай X токенів — отримай Y викликів на місяць), DAO-контрольований whitelist.

function checkAccess(uint256 modelId, address user) public view returns (bool, uint256 remainingCalls) {
    AccessPolicy memory policy = accessPolicies[modelId];
    
    // ERC-721 token gate
    if (policy.requiredNFT != address(0)) {
        if (IERC721(policy.requiredNFT).balanceOf(user) > 0) {
            return (true, policy.nftHolderMonthlyCallLimit);
        }
    }
    
    // ERC-20 staking gate
    if (policy.requiredStake > 0) {
        uint256 staked = stakingVault.stakedBalance(user, policy.stakeToken);
        if (staked >= policy.requiredStake) {
            uint256 calls = (staked / policy.requiredStake) * policy.callsPerStakeUnit;
            return (true, calls);
        }
    }
    
    // Платний доступ через токени висновку
    uint256 tokenId = userInferenceTokens[modelId][user];
    if (tokenId != 0) {
        InferenceToken memory token = inferenceTokens[tokenId];
        if (token.callsRemaining > 0 && block.timestamp < token.expiresAt) {
            return (true, token.callsRemaining);
        }
    }
    
    return (false, 0);
}

Управління та оновлення моделей

Токенізована модель — це живий продукт. Вам потрібен механізм голосування за прийняття нових версій ваг, зміну умов доступу, керування скарбницею (доходи платформи).

Стандартна схема: ERC-20 токен управління + OpenZeppelin Governor + Timelock. AI-специфічне — пропозиції про зміни ваг повинні пройти технічний огляд (перевірка нового weightsHash, тестування на benchmark). Включення на-chain оракула результатів бенчмарку — надлишково на старті, але можливо через Chainlink.

Стек та терміни розроблення

Смарт-контракти: Solidity, OpenZeppelin, Hardhat/Foundry. 8–12 тижнів на повний реєстр із управлінням.

ZK-верифікація: ezkl для моделей до 100M параметрів, RISC Zero для довільного висновку. Підготовка circuit — 4–8 тижнів залежно від архітектури моделі.

Off-chain інфраструктура: Node.js / Python API для прийняття запитів, черги обчислень (Bull/Redis), інтеграція з GPU-провайдерами (Akash, Vast.ai, власний кластер).

Аудит: обов'язковий перед mainnet. Особливу увагу — логіка управління правами доступу та розподіл доходів.

Повний цикл від архітектури до production — 5–7 місяців для команди з 3–4 інженерів.