Python má GIL, v jednu dobu může běžet jen jeden thread, pokud teda funkce (musí to bejt knihovní, nenapsaná, v Pythonu) ten GIL explicitně "neuvolní" na nějakou déle trvající operaci, na kteoru ho nepotřebuje (např. při čekání na IO).
Jen hádám, ale tuším, že problém bude tady - že ty knihovny co používáš si drží GIL a pak se jen ztrácí čas při přepínání kontextu. Jednoduše to zjistíš, když se koukneš (např. top), jestli to vůbec někdy využije více než jedno jádro.
Další možnost je ta, že někdy (vlastně jsem moc nezjišťoval kdy, prostě jsem ji při paralelním výpočtu pro jistotu zrušil vždy) python automaticky nastavuje processu afinitu na jedno jádro. Takže také zkus také zkontrolovat todle (ale myslím, že to problém nebude).