What I Ended Up Doing
I ended up using a combination of pencil and paper and one of the features of Roll20, which we use whether we're geographically distributed or co-located.
Rolling Attacks
In Roll20 it turns out there's a formula for rolling n 20-sided dice, adding t to each die, and counting the number of rolls that exceed a certain threshold.
If you want to roll 10 to-hits, each with a +5, and find out how many hit AC 15, in Roll20 you would use the command:
/roll {10d20+5}>15
Roll20 will then come back with a result, for instance, "5 successes".
Rolling Damage
I could not make the Roll20 interface roll n damage dice and add 1 to each. It would only roll n damage dice and add 1 to the total. Since the critters do 1d4+1 per hit, I considered using:
/roll {nd4}+n
for example:
/roll {5d4}+5
but in the end I ended up using the average damage from the critters' monster entry. I could just do the math in my head to find out the damage.
Combining Critters
I decided the critters would attack in groups of 4. I was intending on groups of 4 to 8, but I actually only did groups of 4.
When a group would attack a PC I would use a single icon to represent the group in Roll20.
I would write down on my notepad, SN-A, SN-B, etc, for each group of critters. (SN was my personal notation for small nasties, which is what their icon said.) Then I would write down four 18's below the heading for that group. (Each critter started out with 18 HP.)
Making Attacks
Each critter makes 3 +4 attacks. I was able to quickly know, okay, that's 12 attacks against AC 15, and I could enter in Roll20:
/roll {12d20+4}>15
It would tell me the number of successes, and I would just calculate the damage in my head. In the case above, if Roll20 told me "4 Successes", I would just do the multiplication in my head and say, 20 points. I would actually narrate it a bit, describing them trying to climb up the PC, or duck under a shield, etc., but in the end that would be the damage.)
When PC's would attack the critters, I was pretty liberal in dishing out the damage. Often if a critter took a near-fatal hit, I would cross that one off and narrate that it ran away. When a group dropped to 2, I would have them run away.
I ended up with as many as 3 groups of the critters with a handful of other monsters, all going on their own initiatives.
In Conclusion
I was pretty happy with the result. I could roll the attacks and manage the critters fast enough that it didn't feel like it was bogging down combat at all.
Using Roll20 was pretty important to the solution. I suspect there are other die rollers out there that I might like better, but Roll20 was great because my players could see my rolls without having to add another app to what we use or even switch to a different one.
If I were to do this in a group where we weren't using Roll20 I would look for a different die roller to allow me to roll large groups of attacks.
One concern is that the damage was a bit swingy. Some groups got wiped out before they ever dealt a point, and one group nearly single-handedly took out the group's 5-level fighter tank. But in the end, I liked that they were easy to kill, but dangerous enough in groups to need to be taken seriously.