zero PII exputer University - Part 1. 1: створення даних зразка (і зображень) локально (Українська (Ukrainian))

zero PII exputer University - Part 1. 1: створення даних зразка (і зображень) локально

Wednesday, 24 December 2025

//

9 minute read

Вхід Частина 1 ми обговорювали філософію: прозорий сегментація без PII. Частина 2 обговорює профілі сеансів, сигнали та визначення сегментів.

Але спочатку: Як ви підтверджуєте все це, не торкаючись даних справжнього клієнта?

Для цієї серії статей я створюю повний штучний набір даних ecommerce локально:

  • Каталог продуктів (назви, описи, мітки, ціни)
  • Анонімне ⇩s} / personas (pids + gones)
  • Зображення продукту (і портрети профілю) за допомогою ComfyUI
  • Необов' язковий імпорт DB, щоб реальна програма могла працювати з ним

Це одна з тих, що відчувають, ніби шахраювання йде вперед: ви отримуєте реалістичні входи, ви можете відновити їх будь-коли, і ви ніколи не впроваджуєте PII у середовище вашого dev.

Чому місцеві синтетичні дані такі потужні

Якщо ви будуєте сегменти / персонализацію, вам потрібні дані, які:

  • У вас достатньо варіацій, щоб зламати наївну евристику.
  • Є безпечним для спільного використання (в коді, тестах, демонстраціях)
  • Чи можна відшліфувати (так, щоб ви могли порівнювати зміни в моделях)

Справжні дані є протилежними: чутливі, безладні, важко пересуватися, і повні історичних відхилень.

Синтетичні дані дають вам три супердержави:

  1. Швидка ітерація: змінити логіку сегментації, відновлення, повторний запуск.
  2. ХардінгCity in New Jersey USA: симулювати дивну довгу дистанцію, яку ви виграли, у крихітному наборі даних dev.
  3. Перевірка з' єднання з поясненням: ви можете Перевірка кожного створеного поля И признайте, что у вас есть то, почему со мной все в порядке.
flowchart LR
    Taxonomy[gadget-taxonomy.json] --> Gen[SampleData generator]
    Gen --> Products[products.json]
    Gen --> Profiles[profiles.json]
    Gen --> Images[images/*]
    Products --> Import[Import into Postgres]
    Profiles --> Import

    style Taxonomy stroke:#1971c2,stroke-width:3px
    style Gen stroke:#1971c2,stroke-width:3px
    style Import stroke:#2f9e44,stroke-width:3px

Інструменталізація (Те, що насправді виконується)

Генератор живе в Mostlylucid.SegmentCommerce.SampleData.

Вона не має права на увазі, що це прагматичний хрест, який промовляє до:

  • Ольямаjapan. kgm (локальний LLM) для структурованого покоління JSON.
  • ComfyUI (локальна різниця) для зображень у стилі фотографії у стилі продукту.
  • А sysonomy JSON за допомогою цього пункту можна зберігати зв' язок між виводами даних (категорій, типи, різновиди, варіанти, діапазони цін).

Налаштування буде переведено так, щоб ви могли здійснювати його за допомогою змінних середовища:

// Mostlylucid.SegmentCommerce.SampleData/Program.cs
var configuration = new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory)
    .AddJsonFile("appsettings.json", optional: true)
    .AddEnvironmentVariables("SAMPLEDATA_")
    .Build();

Швидкий запуск

Ви зазвичай виконуєте три місцевих послуги поруч з генератором:

flowchart LR
    CLI[SampleData CLI] --> Ollama["Ollama
    http://localhost:11434"]
    CLI --> Comfy["ComfyUI
    http://localhost:8188"]
    CLI -. optional .-> DB[(Postgres)]

    style CLI stroke:#1971c2,stroke-width:3px
    style Ollama stroke:#1971c2,stroke-width:3px
    style Comfy stroke:#2f9e44,stroke-width:3px
    style DB stroke:#fab005,stroke-width:3px

Запустити генератор з кореневої теки експропріатора:

dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- status

Після цього створіть набір даних:

# v1 generator: taxonomy + optional Ollama + optional ComfyUI
# Writes ./Output/products.json, ./Output/profiles.json, ./Output/images/...
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --count 20

Корисні перемикачі:

# No LLM calls, taxonomy only
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --no-ollama

# No ComfyUI images
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --no-images

# Write into Postgres (uses configured connection string)
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- generate --db

Зауваження: якщо ComfyUI є наявним, генератор v1 повертається до зображень заповнювача (вона використовує picsum.photosЯкщо ви хочете бути строго локальними, біжіть з --no-images.

V2 Генератор: Sllers → Продукти → Клієнти → Порядок → Вмонтовані

Там також йде новіша команда генератора (gen) яка робить більш повну "плюс-функцію":

# v2 generator
# Writes dataset.json plus sellers/products/customers/orders split files
dotnet run --project Mostlylucid.SegmentCommerce.SampleData -- gen --sellers 50 --products 20 --customers 1000

Він оркеструє як багатофазовий трубопровод:

flowchart LR
    A[Sellers] --> B[Products]
    B --> C[Customers]
    C --> D[Orders]
    D --> E[Embeddings]

    B -. optional .-> I[ComfyUI images]

    style A stroke:#1971c2,stroke-width:3px
    style B stroke:#1971c2,stroke-width:3px
    style C stroke:#1971c2,stroke-width:3px
    style D stroke:#1971c2,stroke-width:3px
    style E stroke:#2f9e44,stroke-width:3px
    style I stroke:#2f9e44,stroke-width:3px

І ви можете побачити ці фази напряму в коді:

// Mostlylucid.SegmentCommerce.SampleData/Services/DataGenerator.cs
// 1. Generate Sellers
// 2. Generate Products for each seller
// 3. Generate Customers
// 4. Generate Orders (with fake checkout data via Bogus)
// 5. Generate embeddings for all entities

Вбудовування (local ONNX, кеш після першого запуску)

Генератор v2 може обчислювати вбудовування за допомогою моделі ONNX (типово: all-MiniLM-L6-v2). Під час першого запуску програма звантажує модель і vocab до вашої теки виводу.

Це означає:

  • Перший запуск потребує доступу до мережі (модель звантаження)
  • Подальші запуски є локальними і швидкими
  • Якщо ви хочете, щоб мережа "no" коли-небудь, виконайте команду --no-embeddings
// Mostlylucid.SegmentCommerce.SampleData/Services/EmbeddingService.cs
private const string ModelUrl = "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/onnx/model.onnx";
private const string VocabUrl = "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main/vocab.txt";

// Download model if not exists
if (!File.Exists(_config.ModelPath))
{
    await DownloadFileAsync(ModelUrl, _config.ModelPath, ct);
}

Як ми робимо це? (лише JSON)

Задаток створення продукту навмисно строгий: LLM повинен повернути лише JSON, з вбудованим прикладом схеми JSON.

// Mostlylucid.SegmentCommerce.SampleData/Services/OllamaProductGenerator.cs
return $"""
    You are a product catalog generator for an e-commerce store. Generate {count} unique, realistic product listings for the \"{category.DisplayName}\" category.

    Category description: {category.Description}
    Example products in this category: {category.ExampleProducts}
    Price range: £{category.PriceRange.Min:F2} - £{category.PriceRange.Max:F2}

    For each product, provide:
    1. A compelling product name (realistic brand-style naming)
    2. A detailed description (2-3 sentences, highlighting key features and benefits)
    3. A realistic price within the range
    4. Optional original price if on sale (20-40% higher than current price)
    5. 3-5 relevant tags
    6. Whether it's trending (about 20% should be trending)
    7. Whether it's featured (about 15% should be featured)
    8. An image prompt for AI image generation (detailed, product photography style)
    9. 2-3 colour variants for the product

    IMPORTANT: Respond with ONLY valid JSON, no markdown formatting, no code blocks, no explanations.

    Generate {count} diverse products now:
    """;

Це має значення через те, що системи знизу (створення зображень + імпорт + вбудовування) хочуть структуровані дані. LM створюється вхідні до трубопроводуЯ не пишу прозу.

Відповідь LLM: аналізу JSON, або відступлення назад

LLM - це не компілятори. Навіть з "JS лише JSO," вам все ще потрібно відсторонюватися і граціозно повернути назад.

Генератор v2 робить це через маленького помічника (LlmService) що витягує перший {...} блок і зменшує його:

// Mostlylucid.SegmentCommerce.SampleData/Services/LlmService.cs
var jsonStart = response.IndexOf('{');
var jsonEnd = response.LastIndexOf('}');

if (jsonStart >= 0 && jsonEnd > jsonStart)
{
    var jsonStr = response.Substring(jsonStart, jsonEnd - jsonStart + 1);
    return JsonSerializer.Deserialize<T>(jsonStr, new JsonSerializerOptions
    {
        PropertyNameCaseInsensitive = true
    });
}

А канал для загального створення явно перевіряє наявність і зниження доступності до детермінуючих шаблонів, якщо потрібно:

flowchart LR
    A[EnableLlm=true?] -->|no| F[Fallback templates]
    A -->|yes| B[GET /api/tags]
    B -->|model present| C[LLM JSON prompts]
    B -->|not available| F

    style A stroke:#1971c2,stroke-width:3px
    style C stroke:#2f9e44,stroke-width:3px
    style F stroke:#fab005,stroke-width:3px

Приклад: клієнтська особа (v2)

Персонал для клієнтів короткий і структурований так, щоб його можна було швидко створити за допомогою невеличкої локальної моделі:

// Mostlylucid.SegmentCommerce.SampleData/Services/DataGenerator.cs
var prompt = $$"""
    Generate a shopper persona interested in: {{string.Join(", ", categoryNames)}}.

    Return JSON only:
    {
      "persona": "Brief persona description (e.g. 'Tech enthusiast who values quality')",
      "name": "Realistic first name",
      "bio": "One sentence about their shopping habits",
      "age": 25,
      "shopping_style": "budget|value|premium|luxury",
      "preferred_categories": ["category1", "category2"]
    }
    """;

ComfyUI: Production Photography через API

ComfyUI є великим, тому що він дає вам контрольований трубопровод (робочий потік), а не зображення у чорній скриньці.

Генератор:

  1. Завантажує шаблон робочого процесу (ComfyUI/workflows/product_image.json)
  2. Латкає запрошення до CLIPTextEncode
  3. Черги /prompt
  4. Опитування /history/{promptId}
  5. Звантажує зображення через /view?...
sequenceDiagram
    participant Gen as SampleData
    participant Comfy as ComfyUI

    Gen->>Comfy: POST /prompt (workflow + prompt)
    Comfy-->>Gen: prompt_id
    loop poll
        Gen->>Comfy: GET /history/{prompt_id}
        Comfy-->>Gen: outputs / images
    end
    Gen->>Comfy: GET /view?filename=...&type=output
    Comfy-->>Gen: PNG bytes

Вибір моделі ComfyUI також латається до робочого процесу під час запуску (так, щоб ви могли поміняти контрольні пункти без редагування JSON):

// Mostlylucid.SegmentCommerce.SampleData/Services/ComfyUIImageGenerator.cs
TryPatchCheckpoint(workflow, _config.ComfyUICheckpointName ?? "sd_xl_base_1.0.safetensors");
TryPatchRefiner(workflow, _config.ComfyUIRefinerName ?? "sd_xl_refiner_1.0.safetensors");

А латки спеціально прості і міцні.

// Mostlylucid.SegmentCommerce.SampleData/Services/ComfyUIImageGenerator.cs
// Update CLIPTextEncode nodes with our prompt
if (classType == "CLIPTextEncode")
{
    var inputs = nodeObj["inputs"]?.AsObject();
    if (inputs != null && inputs.ContainsKey("text"))
    {
        var currentText = inputs["text"]?.GetValue<string>() ?? "";
        if (!currentText.Contains("bad") && !currentText.Contains("ugly") && !currentText.Contains("deformed"))
        {
            inputs["text"] = prompt;
        }
    }
}

// Update image dimensions
if (classType == "EmptyLatentImage")
{
    var inputs = nodeObj["inputs"]?.AsObject();
    if (inputs != null)
    {
        inputs["width"] = _config.ImageWidth;
        inputs["height"] = _config.ImageHeight;
    }
}

Профілі і особи (корисно, а не похмуро)

Генератор v1 створює анонімні профілі, а потім збагачує їх за допомогою персони (все ще немає п' ятної). У результаті у вас з' являється реалістична " люди- } тестові дані без листів електронної пошти, адрес або будь- чого іншого, що ви могли б випадково відправити.

У V1, профілі, в основному, використовують гаш, так що там нічого не йде до }rese):

// Mostlylucid.SegmentCommerce.SampleData/Services/ProfileGenerator.cs
var profileKey = Hash($"fp-{Guid.NewGuid():N}");

private static string Hash(string input)
{
    using var sha = SHA256.Create();
    var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(input));
    return Convert.ToHexString(bytes).ToLowerInvariant();
}

Це точно передає думки всієї серії: ви можете вилити те, що ви ніколи не зберігали.

flowchart TB
    Signals["Generated signals
    views/cart/purchase weights"] --> Persona["Persona enrichment
    Ollama JSON-only"]
    Persona --> Portrait[Portrait prompt]
    Portrait --> Comfy[ComfyUI]

    style Signals stroke:#1971c2,stroke-width:3px
    style Persona stroke:#1971c2,stroke-width:3px
    style Comfy stroke:#2f9e44,stroke-width:3px

Доказ: що це дає вам нагоду доказати

Цей локальний трубопровод потужний, тому що він підтримує моделювання перевіркиНе лише демонстрації.

  • Розум сегментації: чи є сегменти, які ви розраховуєте, що ми маємо на увазі, коли ви переглядаєте назви продуктів/ґи і створюєте особи?
  • Рекомендація для пояснення: чи можу я зрозуміти, чому потрібно вказувати на справжній сигнал, який ви можете перевірити?
  • Холодний початок: якщо ви знищите набір даних і відтворюєте їх, чи прогнозується поведінка системи?
  • Перевірка регресії: Регенерувати ту ж форму даних і переконатися, що ваші зміни не перекриють оцінки, оцінки, оцінки та інтерфейсу користувача.

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

Що наступне

**Частина 2**Е-е-е-е-е-е-е-е-е-е-е-е-е-еф-еф-еф-еф-еф-еф-еф-еф-еф-еф-еф-еф-е...

Частина 3 Шаблон вихідних, черга завдань і інтерфейс прозорості.


Код генератора: Mostlylucid.SegmentCommerce.SampleData/

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.