aidoc.uz

5-qism · AI muhandisi uchun Python·25-bob

Performans, toza kod va keyingi qadamlar: AI/ML yo'l xaritasi

O'lchamasdan optimallashtirmang: timeit, cProfile, tracemalloc; algoritmik murakkablik va to'g'ri ma'lumot tuzilmasi; keshlash va vektorlashtirish; professional kod mezonlari; kurs bo'yicha o'z-o'zini tekshirish va ML/AI Engineering'ga yo'l xaritasi.

Oxirgi bob ikki qismdan iborat. Birinchisi — performans: kod sekin bo'lsa, qanday qilib sababini topish va tuzatish. Ikkinchisi — yo'l xaritasi: bu kursdan keyin ML Engineering va AI Engineering'ga qanday o'tish, nimani, qaysi tartibda o'rganish va o'zingizni qanday tekshirish.

▶ Video dars· PyCon 2018· 28:51· ingliz tilida
Ned Batchelder - Big-O: How Code Slows as Data Grows - PyCon 2018

Big-O murakkablik: kod ma'lumot o'sishi bilan qanday sekinlashadi — bobning 3-bo'limidagi g'oya PyCon ma'ruzasida.

YouTube'da ochish ↗

1. Optimallashtirishning birinchi qoidasi#

"Premature optimization is the root of all evil." — Donald Knuth

Ko'p dasturchilar kodni "tezroq bo'lsin" deb murakkablashtiradi — va ko'pincha noto'g'ri joyni. Dastur vaqtining 90% i odatda kodning 10% ida o'tadi. O'sha 10% ni taxmin bilan topib bo'lmaydi — o'lchash kerak.

  1. To'g'ri ishlashini ta'minlang

    Testlar bilan (16-bob). Tez, lekin noto'g'ri kod — foydasiz.
  2. Yetarlicha tezmi?

    Kun bir marta ishlaydigan 3 soniyalik skript — optimallashtirish shart emas.
  3. O'lchang

    Profiler bilan qayerda vaqt ketayotganini toping.
  4. Eng katta muammoni tuzating

    Odatda algoritm yoki ma'lumot tuzilmasi — "mikro-optimallashtirish" emas.
  5. Qayta o'lchang

    Yaxshilanish haqiqatan bo'ldimi? Testlar hali o'tyaptimi?

2. O'lchash vositalari#

timeit — kichik kod bo'laklarini solishtirish#

import timeit
 
setup = "items = list(range(100_000)); s = set(items); q = list(range(0, 200_000, 20))"
timeit.timeit("sum(1 for x in q if x in items)", setup, number=1)   # ~2.16 s
timeit.timeit("sum(1 for x in q if x in s)", setup, number=1)       # ~0.0005 s

Jupyter'da: %timeit expr (22-bob). timeit kodni ko'p marta ishlatib, tasodifiy shovqinni kamaytiradi.

cProfile — butun dastur qayerda vaqt sarflaydi#

Mana real misol — matn korpusidan lug'at quruvchi kod (6-bob amaliyotiga o'xshash):

# vocab.py
import re
from collections import Counter
 
 
def tokenize(text):
    return re.findall(r"\w+", text.lower())
 
 
def build_vocab(docs, stop_words):
    counts = Counter()
    for doc in docs:
        for tok in tokenize(doc):
            if tok not in stop_words:
                counts[tok] += 1
    return counts
 
 
def main():
    docs = ["Python ML uchun eng mashhur til va u juda qulay"] * 20000
    stop_words = ["va", "u", "uchun", "eng", "juda"] * 200      # ro'yxat
    build_vocab(docs, stop_words)
 
 
if __name__ == "__main__":
    main()
python -m cProfile -s cumtime vocab.py
         120139 function calls (120135 primitive calls) in 0.374 seconds
 
   Ordered by: cumulative time
 
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.374    0.374 vocab.py:15(main)
        1    0.344    0.344    0.374    0.374 vocab.py:7(build_vocab)
    20000    0.004    0.000    0.030    0.000 vocab.py:4(tokenize)
    20000    0.017    0.000    0.017    0.000 {method 'findall' of 're.Pattern' objects}

O'qish: tottime — funksiyaning o'zida o'tgan vaqt (chaqirgan funksiyalarisiz), cumtime — hammasi bilan. build_vocabning o'zi 0.344 s — regex (tokenize) atigi 0.030 s. Demak muammo regex'da emas, siklning o'zida — aniqrog'i tok not in stop_words qatorida: stop_words — 1000 elementli ro'yxat, har tekshiruv O(n).

Bitta o'zgarish:

stop_words = set(["va", "u", "uchun", "eng", "juda"] * 200)    # set — O(1) tekshiruv
         120139 function calls (120135 primitive calls) in 0.044 seconds

8.5 baravar tezroq — bitta so'z bilan. Regex'ni "optimallashtirishga" vaqt sarflaganingizda, natija deyarli o'zgarmas edi. Profiler bo'lmasa, buni taxmin qilish qiyin.

Vizual tahlil uchun: uv add --dev snakeviz → python -m cProfile -o prof.out vocab.py → snakeviz prof.out. Qatorma-qator o'lchash uchun — line_profiler; ishlab turgan jarayonni tekshirish uchun — py-spy (kodni o'zgartirmasdan).

tracemalloc — xotira#

import tracemalloc
 
tracemalloc.start()
data = [i * i for i in range(1_000_000)]
current, peak = tracemalloc.get_traced_memory()
print(f"joriy: {current / 1e6:.1f} MB, cho'qqi: {peak / 1e6:.1f} MB")    # ~40 MB
tracemalloc.stop()

Million son — 40 MB (2-bob: har int — obyekt). NumPy'da — 8 MB. Generator bilan (7-bob) — deyarli nol.

3. Algoritmik murakkablik — eng katta yutuqlar shu yerda#

Big-O — ma'lumot hajmi oshganda vaqt qanday o'sishi. Aniq soniyalar emas, o'sish tezligi:

MurakkablikNomin = 1 000n = 1 000 000Misol
O(1)Doimiy11dict[k], x in set, lst[i]
O(log n)Logarifmik1020bisect (5-bob)
O(n)Chiziqli1 0001 000 000x in list, sum, bitta sikl
O(n log n)10 00020 000 000sorted()
O(n²)Kvadratik1 000 00010¹² — soatlarIchma-ich sikl, siklda x in list

Python tuzilmalari amallarining narxi (5–6-boblar xulosasi):

Amallistdict / setdeque
Indeks bo'yicha [i]O(1)—O(n)
Oxiriga qo'shishO(1)O(1)O(1)
Boshiga qo'shish / boshidan olishO(n)—O(1)
x in ...O(n)O(1)O(n)
Kalit bo'yicha olish—O(1)—
SaralashO(n log n)——

Eng ko'p uchraydigan O(n²) tuzoqlari:

# 1. Siklda ro'yxatdan qidirish
for user in users:                    # n
    if user.id in banned_ids_list:    # × n  → O(n²)
        ...
banned = set(banned_ids_list)         # ✅ bir marta O(n), keyin har tekshiruv O(1)
 
# 2. Siklda satr yig'ish (3-bob)
result = ""
for part in parts:
    result += part                    # har safar yangi satr — 100k bo'lakda ~10× sekinroq
result = "".join(parts)               # ✅
 
# 3. Siklda pop(0)
while queue:
    item = queue.pop(0)               # O(n) har safar
queue = deque(queue)                  # ✅ popleft() — O(1)
 
# 4. Ikki ro'yxatni "birlashtirish" ichma-ich sikl bilan
for order in orders:
    for user in users:
        if order.user_id == user.id: ...
users_by_id = {u.id: u for u in users}    # ✅ lug'at indeksi, keyin O(1) qidiruv

Oxirgisi — Pandas'dagi merge (20-bob) ichkarida aynan shunday ishlaydi.

4. Tezlashtirish usullari — samaradorlik tartibida#

UsulOdatiy yutuqBob
To'g'ri algoritm / ma'lumot tuzilmasi10–10 000×5, 6, 25
Vektorlashtirish (NumPy/Pandas)10–100×19, 20
Keraksiz ishni qilmaslik: keshlash, erta to'xtatish, dangasalik2–1000×7, 8, 14
I/O parallelligi (async, threads) — LLM, tarmoqso'rovlar soniga proporsional17
CPU parallelligi (process'lar)yadrolar soniga yaqin17
Tayyor tez kutubxona (polars, orjson, numba)2–50×—
Mikro-optimallashtirish (lokal o'zgaruvchi, metodni keshlash)5–20%—

Keshlash#

from functools import lru_cache
 
 
@lru_cache(maxsize=10_000)
def embed(text: str) -> tuple[float, ...]:     # tuple — hashlanadi va o'zgarmas
    return tuple(call_embedding_api(text))     # bir xil matn uchun API qayta chaqirilmaydi

LLM ilovalarida keshlash — tezlik va pul: bir xil savollar uchun javob keshi (14-bobdagi disk keshi), embedding keshi, prompt caching (23-bob).

Python'dan tashqariga chiqish#

Profil ko'rsatsa-yu, sof Python sikli baribir sekin bo'lsa:

  • NumPy/Pandas'ga o'tkazing (deyarli har doim birinchi variant);
  • Polars — Pandas'ga o'xshash, Rust'da yozilgan, ko'p hollarda 5–20× tez;
  • Numba — @njit dekoratori bilan sonli funksiyani mashina kodiga kompilyatsiya;
  • Cython / Rust (PyO3) — eng og'ir holatlar uchun.

ML'da esa og'ir hisob baribir GPU'da (PyTorch) bo'ladi — Python faqat boshqaradi (1-bob, "yelim til").

5. Professional kod — o'zingizni tekshiring#

Kod faqat ishlashi kerak emas — uni boshqalar (va 6 oydan keyingi siz) o'qishi, o'zgartirishi va unga ishonishi kerak. Har bir loyihangizni shu ro'yxat bo'yicha tekshiring:

MezonSavolBob
Muhituv sync bilan har qanday kompyuterda bir xil muhit tiklanadimi?9
Tuzilmasrc-layout, mantiqiy modullar, __main__ himoyasi?9
NomlarFunksiya nomi nima qilishini aytadimi? Sehrli satr/sonlar yo'qmi?8, 13
FunksiyalarHar biri bitta vazifa, qisqa, yon ta'sirsiz?8
TiplarType hint'lar, mypy o'tadi? Tashqi ma'lumot — Pydantic?15
XatolarAniq istisnolar, except: pass yo'q, tushunarli xabarlar?10
Loglarprint emas logging; sirlar logda yo'q?10
TestlarMuhim mantiq testlangan, tashqi API'lar fake bilan?16
Sifatruff check, ruff format, pre-commit, CI?16
TakrorlanuvchanlikSeed'lar, versiyalar, konfiguratsiya saqlanadimi?18, 22
XavfsizlikKalitlar .envda, SQL parametrli, pickle ishonchsiz manbadan emas, LLM chiqishiga ko'r-ko'rona ishonch yo'q?9, 11, 18, 23
HujjatREADME: nima qiladi, qanday o'rnatiladi, qanday ishlatiladi?—

6. Kurs bo'yicha o'z-o'zini tekshirish#

Quyidagi savollarga kodni ochmasdan javob bera olsangiz — Python poydevoringiz ML/AI uchun tayyor:

  1. Obyektlar va xotira

    b = a dan keyin a.append(1) nega bni ham o'zgartiradi, a = a + [1] esa yo'q? Mutable default argument nega xavfli?
  2. To'plamlar

    Million elementli ro'yxatda x in lst va to'plamda x in s farqi nima va nega? Qaysi tiplar lug'at kaliti bo'la oladi?
  3. Iteratorlar

    Generator ikkinchi marta aylanilganda nima bo'ladi? 50 GB faylni xotiraga sig'dirmasdan qanday qayta ishlaysiz?
  4. Funksiyalar

    Closure nima va sikldagi lambda'lar nega oxirgi qiymatni "ko'radi"? Dekorator qanday yoziladi?
  5. OOP

    __eq__ yozilsa __hash__ga nima bo'ladi? super().__init__() nega kerak? Dataclass va Pydantic qachon?
  6. Xatolar

    raise ... from e nima beradi? Qaysi HTTP xatolarida qayta urinish kerak?
  7. Parallellik

    GIL nima va qachon threadlar yordam beradi? 1000 ta LLM so'rovini limit bilan qanday parallel yuborasiz?
  8. NumPy/Pandas

    Broadcasting qoidasi? View va copy farqi? df[mask]['col'] = x nega ishlamaydi?
  9. ML ish jarayoni

    Data leakage nima, qanday oldini olasiz? Nega test qismiga faqat bir marta qaraladi?
  10. LLM

    stop_reason qiymatlari nimani bildiradi? Tool use sikli qanday ishlaydi? Prompt caching qachon ishlamaydi?

Javob bera olmagan savolingiz bo'lsa — tegishli bobga qayting va misollarni REPL'da qayta yozib ko'ring.

7. Yo'l xaritasi: bu kursdan keyin#

Python — poydevor. Keyingi qadamlar yo'nalishingizga qarab:

Siz shu yerdasiz: Python (bu kurs)
til, ekotizim, NumPy, Pandas, scikit-learn, LLM API, FastAPI
Matematika (parallel ravishda)
chiziqli algebra, ehtimollar va statistika, hosilalar va gradient — ML'ni 'tushunish' uchun
Ikki yo'l ajraladi
ML Engineering — modellarni qurish va o'qitish; AI Engineering — tayyor modellar ustida mahsulot qurish
Har ikkisi uchun: amaliy loyihalar portfoliosi
GitHub'da, README va natijalar bilan

ML Engineering yo'li#

BosqichMavzularVositalar
1. Klassik MLRegressiya, daraxtlar, ansambllar, klasterlash, xususiyatlar muhandisligi, baholashscikit-learn, XGBoost/LightGBM
2. Deep learningNeyron tarmoqlar, backprop, optimizatorlar, CNN, RNN, TransformerPyTorch
3. NLP / LLMTokenizatsiya, embedding'lar, fine-tuning, LoRAHugging Face Transformers, PEFT
4. MLOpsTajribalarni kuzatish, model registri, deploy, monitoringMLflow / W&B, Docker, FastAPI
5. MasshtabGPU, distributed training, ma'lumotlar pipeline'lariPyTorch DDP, Ray, Spark

AI Engineering yo'li#

BosqichMavzularVositalar
1. LLM API'larPrompt engineering, structured output, streaming, narx va kechikishAnthropic/OpenAI SDK (23-bob)
2. RAGChunking, embedding'lar, vektor qidiruv, reranking, baholashNumPy (19-bob), pgvector/Qdrant
3. AgentlarTool use, rejalashtirish, xotira, ko'p agentli tizimlar, MCPSDK tool runner, Claude Agent SDK
4. EvalOltin datasetlar, LLM-as-judge, regressiya testlaripytest (16-bob), Pandas (20-bob)
5. ProductionKuzatuv, xavfsizlik (prompt injection), xarajat, keshlash, rate limitFastAPI (24-bob), Redis, OpenTelemetry

aidoc.uz'dagi boshqa kitoblar shu yo'lni davom ettiradi: "AI Engineering — 0 dan boshlab", "OpenAI API bilan ishlash", "AI agentlar qurish" va "AI agentlarni amaliyotda qurish". Endi ulardagi har bir kod misolini to'liq tushunasiz.

8. Yakuniy loyiha#

O'rganganlaringizni birlashtiruvchi loyiha — portfoliongizning birinchi jiddiy ishi bo'lishi mumkin:

Amaliy topshiriq

Yakuniy loyiha: o'zbekcha sharhlar tahlili platformasi

Maqsad: o'zbekcha mahsulot sharhlarini tasniflaydigan va tahlil qiladigan servis.

  1. Dataset (11, 20-boblar): kamida 300 ta sharh (o'zingiz yozing, ochiq manbalardan yig'ing yoki LLM bilan yarating va qo'lda tekshiring). Tozalash: apostroflar, dublikatlar, bo'sh qatorlar. JSONL formatda, train/test bo'linishi bilan.
  2. Baseline model (22-bob): TF-IDF + LogisticRegression, o'zbekcha tokenizatsiya bilan. CV natijasi va test'dagi classification report.
  3. LLM tasnifchi (17, 23-boblar): Claude bilan structured output (sentiment, topics, summary), async + Semaphore bilan butun test qismini tasniflash, narx va kechikishni hisoblash.
  4. Solishtirish (20, 21-boblar): ikkala yondashuv uchun aniqlik, narx, kechikish jadvali va grafiklar. Qaysi holatda qaysi biri afzal — yozma xulosa.
  5. Servis (24-bob): FastAPI — /classify (tezkor baseline), /analyze (LLM, streaming bilan), API kaliti, kirish cheklovlari.
  6. Sifat (15, 16-boblar): type hint'lar + mypy, kamida 20 ta test (LLM — fake bilan), ruff, pre-commit, GitHub Actions.
  7. Hujjat: README — arxitektura sxemasi, o'rnatish, natijalar jadvali.
Maslahatni ko'rsatish

Har bir qismni alohida boblar bilan bog'lang: dataset — 11, 20; model — 22; LLM — 17, 23; servis — 24; sifat — 15, 16. Avval eng sodda ishlaydigan versiya (end-to-end), keyin yaxshilang.

9. Xayrlashuv o'rniga#

Dasturlashni o'rganishning yagona yo'li — dasturlash. Bu kursdagi har bir bob — xarita, lekin yo'lni oyog'ingiz bilan bosib o'tishingiz kerak: mashqlarni yeching, xato qiling, traceback'larni o'qing, profiler bilan o'lchang, testlar yozing, loyihalar quring.

Ikki maslahat:

  • Har kuni oz-ozdan kod yozing. Haftada bir marta 7 soat emas — har kuni 1 soat. Ko'nikma takrorlash bilan mustahkamlanadi.
  • AI yordamchilardan to'g'ri foydalaning. Ular kod yozishni tezlashtiradi, lekin siz kodni tushunishingiz va tekshira olishingiz kerak. Bu kurs aynan shuning uchun: AI yozgan kodda mutable default, data leakage, except: pass yoki prompt injection teshigini ko'ra oladigan muhandis — AI davrining eng qadrli mutaxassisi.

Omad! 🚀

Yodda saqlang
  • 01Avval to'g'ri, keyin o'lchang (timeit, cProfile, tracemalloc), keyin eng katta muammoni tuzating.
  • 02Eng katta yutuqlar — algoritm va ma'lumot tuzilmasidan: siklda list'dan qidirish o'rniga set/dict.
  • 03Keyingi qadamlar: vektorlashtirish, keshlash, parallellik; mikro-optimallashtirish — oxirida.
  • 04Professional kod: takrorlanuvchan muhit, tiplar, testlar, loglar, xavfsizlik, hujjat.
  • 05ML Engineering: klassik ML → PyTorch → Transformers → MLOps; AI Engineering: LLM API → RAG → agentlar → eval → production.
  • 06Yakuniy loyiha — kursning barcha qismlarini birlashtirib, portfolio boshlang.

Mustahkamlash

Test va amaliy masalalar

Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.

Test: topshirilmaganMasalalar: 0/3

Bilimni tekshirish

Bob bo'yicha test

12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.

Amaliy masalalar

Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.

01Tartibni saqlagan holda dublikatlarni olib tashlash (tez)

dedupe(items) — birinchi uchragan tartibni saqlab dublikatlarni olib tashlasin. O(n) bo'lishi kerak: if x not in natija_royxati (O(n²)) yondashuvi 200 000 element uchun juda sekin — test vaqtni ham tekshiradi.

02Ikki son yig'indisi (O(n))

two_sum(nums, target) — yig'indisi target ga teng ikki turli element indekslarini (i, j) (i < j) qaytarsin, yo'q bo'lsa None. Ichma-ich sikl emas — lug'at bilan bir o'tishda.

03Memoizatsiya

count_paths(rows, cols) — rows × cols to'rning chap-yuqori burchagidan o'ng-pastki burchagiga faqat o'ngga yoki pastga yurib nechta yo'l borligini rekursiya + functools.lru_cache bilan hisoblasin. count_paths(18, 18) bir zumda.